Search code examples
winui-3icommandcontentdialog

ContentDialog - What to Use For SecondaryButtonCommand


I am creating a general purpose Exception message dialog, and want to have a "Copy Error" button to copy the error text to the clipboard. I cannot figure out what to use for SecondaryButtonCommand = ICommand.

All my research about implementing ICommand with WinUI 3 ends up on some variation of RelayCommand and MVVM Toolkit, which I could not get to work.

I got the Copy to Clipboard to work. I now want that to happen when user clicks a button on the dialog.

Note this dialog is created in its own class in code, and is intended to be used from any page.

What do I use for SecondaryButtonCommand = ???

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using Windows.ApplicationModel.DataTransfer;

namespace JimPrototypes2.Helpers
{
   public static class ErrorDialog 
    {
         public static void Show(XamlRoot root,  string message, string stackTrace)
        {
            string msg = message + Environment.NewLine + Environment.NewLine + stackTrace;
   
            ContentDialog err = new ContentDialog()
            {
                XamlRoot = root,
                Title = "An Error Has Occured",
                Content = msg,
                CloseButtonText = "Ok",
                SecondaryButtonText = "Copy Error",
                SecondaryButtonCommand = ???????      
            };

            err.ShowAsync();

            // Just testing copy to clipboard
            DataPackage package = new DataPackage();
            package.SetText(msg);
            Clipboard.SetContent(package);
        }      
    }
}

Solution

  • Eventually came across an ICommand example that helped. Turns out it is REALLY easy once I saw a simple, functional example.

    Here is my ICommand named CopyCommand

    using System;
    using System.Windows.Input;
    using Windows.ApplicationModel.DataTransfer;
    
    namespace JimPrototypes2.Helpers
    {
        class CopyCommand : ICommand
        {
            string _copyText;
    
            public CopyCommand(string input)
            {
                _copyText = input;
            }
            public bool CanExecute(object parameter)
            {
                return true;
            }
            public void Execute(object parameter)
            {
                DataPackage package = new DataPackage();
                package.SetText(_copyText);
                Clipboard.SetContent(package);
            }
    
            public event EventHandler CanExecuteChanged;
        }
    }
    

    My updated ErrorDialog class

    using Microsoft.UI.Xaml;
    using Microsoft.UI.Xaml.Controls;
    using System;
    
    namespace JimPrototypes2.Helpers
    {
       public static class ErrorDialog 
        {
             public static void Show(XamlRoot root,  string message, string stackTrace)
            {
                string msg = message + Environment.NewLine + Environment.NewLine + stackTrace;
    
                CopyCommand cmd = new CopyCommand(msg);
    
                ContentDialog err = new ContentDialog()
                {
                    XamlRoot = root,
                    Title = "An Error Has Occured",
                    Content = msg,
                    CloseButtonText = "Ok",
                    SecondaryButtonText = "Copy Error",
                    SecondaryButtonCommand = cmd      
                };
    
                err.ShowAsync();
            }      
        }
    }
    

    And using it in a try catch block in a BackgroundWorker thread

     private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
     {
         try
         {
             _backup.Backup(_folders);
         }
         catch (Exception ex)
         {
             DispatcherQueue.TryEnqueue(() => {  
                 ErrorDialog.Show(this.XamlRoot, ex.Message, ex.StackTrace);                  
             });
         }
     }