views:

105

answers:

3

hi, i lately had the problem of creating add and edit dialogs for my wpf app. all i want to do in my code was something like this. (I mostly use viewmodel first approach with mvvm)

ViewModel which calls a dialog window:

 var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);

 ... do anything with the dialog result...

how does it works?

first i created a dialogservice

public interface IUIWindowDialogService
{
    bool? ShowDialog(string titel, object datacontext);
}

public class WpfUIWindowDialogService : IUIWindowDialogService
{
    public bool? ShowDialog(string titel, object datacontext)
    {
        var win = new WindowDialog();
        win.Title = titel;
        win.DataContext = datacontext;

        return win.ShowDialog();
    }

}

WindowDialog is a specail but simple window. i need it to hold my content:

<Window x:Class="WindowDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    Title="WindowDialog" 
    WindowStyle="SingleBorderWindow" 
    WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight">
    <ContentPresenter x:Name="DialogPresenter" Content="{Binding .}">

    </ContentPresenter>
</Window>

a problem with dialogs in wpf is the dialogresult=true. this can only achieve in code. thats why i created an interface for my dialogviewmodel to implement.

public interface IDialogResultVMHelper
{
    event EventHandler DialogResultTrueEvent;
}

when ever my viewmodel think its time for dialogresult=true, then raise this event :)

for my WindowDialog this means register to this event:

public partial class WindowDialog : Window
{
    public WindowDialog()
    {
        InitializeComponent();
        this.DialogPresenter.DataContextChanged += DialogPresenterDataContextChanged;
    }

    private void DialogPresenterDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var d = e.NewValue as IDialogResultVMHelper;

        if(d == null)
            return;

        d.DialogResultTrueEvent += DialogResultTrueEvent;
    }

    private void DialogResultTrueEvent(object sender, EventArgs e)
    {
        this.DialogResult = true;
    }
}

now at least i have to create an datatemplate in my resource file(app.xaml or something)

<DataTemplate DataType="{x:Type DialogViewModel:EditOrNewAuswahlItemVM}" >
        <DialogView:EditOrNewAuswahlItem/>
</DataTemplate>

well thats all, i can now call dialogs from my viewmodels:

 var result = this.uiDialogService.ShowDialog("Dialogwindow title goes here", dialogwindowVM);

now my question, do you see any problems with this solution?

+1  A: 

This is a good approach and I used similar ones in the past. Go for it!

One minor thing I'd definitely do is make the event receive a boolean for when you need to set "false" in the DialogResult.

event EventHandler<bool> RequestCloseDialog;
Julian Dominguez
thx, i will change my event :)
blindmeis
+1  A: 

I've been using an almost identical approach for several months now, and I'm very happy with it (i.e. I haven't yet felt the urge to rewrite it completely...)

In my implementation, I use a IDialogViewModel that exposes things such as the title, the standad buttons to show (in order to have a consistent apparence across all dialogs), a RequestClose dialog, and a few other things to be able to control the window size and behavior

Thomas Levesque
thx, the title should really go in my IDialogViewModel. the other properties like size, standard button i will leave, because this all comes from the datatemplate at least.
blindmeis
That's what I did at first too, just use SizeToContent to control the size of the window. But in one case I needed to make the window resizable, so I had to tweak it a little...
Thomas Levesque
mhh thx for this info :)
blindmeis
A: 

You might be interested in the ViewModel sample application of the WPF Application Framework (WAF). It shows an alternative approach for showing dialog windows in a MVVM application.

jbe