.Net, C#, Design, Material Design, UI, UX, WPF, xaml

WPF Dialog Boxes In Material Design In XAML Toolkit

(Note this article refers to a pre-release version, which can be found on nuget provided pre-release versions are included in your search.)

Message boxes.  Ever a source of frustration in WPF.  MahApps has some nice dialog boxes to which I recently helped out with an MVVM API, but Material Design In XAML Toolkit can run with or without MahApps so I wanted a custom implementation which would meet these goals:

  • Look similar to the dialogs we see on Android phones
  • Have an API which is useable from XAML, code-behind, and MVVM
  • Provide full flexibility on the content of the dialog.

All software is evolution and after a reasonable attempt of doing something similar for a client – which ended up with a bit of a code-smell around callbacks from the API – I’ve come up some composable pieces which I hope are flexible, easy to use, and – most importantly – provide an attractive GUI 🙂

The cornerstone is the DialogHost control.  It’s a content control, meaning the underlying content over which the popup dialog will be displayed can be targeted; to a specific area of your app, or the entire Window content.


<md:DialogHost>
    <md:DialogHost.DialogContent>
        <dialogContent />
    </md:DialogHost.DialogContent>
    <mainContent />
</md:DialogHost>

When the dialog is open, the underlying content will be dimmed and disabled.

Material Design Dialog

DialogHost.DialogContent (associated with DialogHost.DialogContentTemplate) is your typical XAML content object property for setting the content of your dialog.  You can infer from this that you can use MVVM to bind content, but there are multiple ways of populating the content, showing the dialog, closing the dialog, and processing responses, so here’s a list of all the strategies for using the dialog (after the gif):

Material Design Dialog

Open Dialog Strategies

DialogHost.OpenDialogCommand

<Button Command="{x:Static md:DialogHost.OpenDialogCommand}" />

RoutedCommand typically used from a button where optional content can be provided via the CommandParameter.

DialogHost.IsOpen

<md:DialogHost IsOpen="True" />

Dependency property, to be triggered from XAML, set from code-behind or via a binding.  Content must be set in DialogHost.DialogContent.

DialogHost.Show

DialogHost.Show(viewOrModel);

Async/await based static API which can be used purely in code (for example from in a view model).  Content can be passed directly to the dialog.

Close Dialog Strategies

DialogHost.CloseDialogCommand

<Button Command="{x:Static md:DialogHost.CloseDialogCommand}" />

RoutedCommand, typically used on buttons inside the dialog, where the command parameter will be passed along to the dialog response.

DialogHost.IsOpen

<md:DialogHost IsOpen="False" />

Dependency property, to be triggered from XAML, set from code-behind or via a binding.

HANDLE CLOSE STRATEGIES

The DialogClosingEventHandler delegate is key.  It provides the parameter provided to DialogHost.CloseDialogCommand, and allows the pending close to be cancelled.

The following mechanisms allow handling of this event, via code-behind, MVVM practices, or just from the code API:

DialogHost.DialogClosing

<md:DialogHost DialogClosing="DialogHost_OnDialogClosing" />

Bubbling RoutedEvent, which could be used in code-behind.

DialogHost.DialogClosingAttached

<Button Command="{x:Static wpf:DialogHost.OpenDialogCommand}" md:DialogHost.DialogClosingAttached="DialogHost_OnDialogClosing" />

Attached property, which accepts a DialogClosingEventHandler which makes it easy to subscribe to the closing event in a more localized area of XAML.

DialogClosing.DialogClosingCallback

<md:DialogHost DialogClosingCallback="{Binding DialogClosingHandler}" />

Standard dependency property which enables the a DialogClosingEventHandler implementation to be bound in, typically from a view model.

DialogHost.Show

var result = await DialogHost.Show(viewOrModel, ClosingEventHandler);

The async response from this method returns the parameter provided when DialogHost.CloseDialogCommand was executed.  As part of the Show() signature a DialogClosingEventHandler delegate can be provided to intercept the on-closing event, just prior to the close.

More Examples

More complete usage examples can be found in MainDemo.Wpf which is part of the Toolkit solution, primarily in MainDemo.Wpf/Dialogs.xaml.

Advertisements

23 thoughts on “WPF Dialog Boxes In Material Design In XAML Toolkit

  1. Can you help me please how can I create message dialog box for as popup for alert. I am trying from last few days but the problem is that when I try to call dialog box without MVVm from C# the button becomes disabled.

    Can you help me please how to create dialog box without MVVM like warning popup message box.

    Thanks in advance 🙂

    1. Hi…if your button is disabled I suspect it is outside of the DialogHost. Either put a DialogHost at the root of all your XAML (so that the button is inside it somewhere), or specify the CommandTarget on your button to point to your DialogHost.

  2. Nop button is inside. Even I downloaad your demo app. Ony sample 1 working other buttons are disabled. If you just writte a simple code without MVVM like messagebox then it would be great help for me. and I just call it from external button from code behind not from xaml. I am not a good programmer. 😦 Thanks!

  3. Hi, I have a conceptual question about how you give feedback to user if you’re already in a dialog box. On my main window I call a DialogHost.Show and pass a user control as parameter, where the user can input some data. But I need to give the user some information if an error occurs. I’m doing this using DialogHost,Show again but then I get this error: DialogHost is already open. Do you have any advice on this?

  4. Hi! Recently I want to do a dialog box with a GIF loading, but it’s closed when you perform a function, how can I do this? Any idea? Or other ways? The dialog box opens when a button is pressed and hopefully close automatically. Thank you.

    1. If I understand what your are saying, you want to use the dialog .Session to closer the dialog when you are ready. You can get the Session from the opening event arguments.

  5. Hi James,
    Thanks for this great library.
    Is there a way to apply the current theme to the Dialog Boxes?
    When I use dark theme my dialogs have always light theme!
    Thanks.

  6. That is by design… But yes you can, but you have to apply the Dark resource locally…I might make this optional in future though… Stop by the Gitter chatroom (link on project page) if you want to chat further

  7. How can I open a loading dialog from code C#. I want to load some data from the data bank, I created a new thread and I would like to use the Material Design dialog. I am currently using Busy indicator from Xceed, but it does no match the Material Design.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s