2

This is my current App.xaml.cs

Its looks simple for one or two, but I have 7-8 windows. Is there a clever way to make this a little more general and better?

public App()
{
    _ViewModel = new MyAppViewModel();

    _ViewModel.OpenXXXWindowEvent += new EventHandler(ViewModel_OpenXXXWindow);
    _ViewModel.OpenYYYWindowEvent += new EventHandler(ViewModel_OpenYYYWindow);
    ...
}

private void ViewModel_OpenXXXWindow(object sender, EventArgs e)
{
    _XXXWindow = new XXXWindow();
    _XXXWindow.DataContext = _ViewModel;
    _XXXWindow.ShowDialog();
}

private void ViewModel_CloseXXXWindow(object sender, EventArgs e)
{
    if (_XXXWindow != null)
        _XXXWindow.Close();
}

private void ViewModel_OpenYYYWindow(object sender, EventArgs e)
{
    _YYYWindow = new YYYWindow();
    _YYYWindow.DataContext = _ViewModel;
    _YYYWindow.ShowDialog();
}

private void ViewModel_CloseYYYWindow(object sender, EventArgs e)
{
    if (_YYYWindow != null)
        _YYYWindow.Close();
}

...
AndyUK
  • 3,933
  • 7
  • 42
  • 44
BlackCat
  • 521
  • 3
  • 8
  • 22

2 Answers2

2

Too much XAML code-behind is a signal that you're somehow breaking the MVVM pattern. A ViewModel receiving EventArgs is a no-no too.

To open/close dialogs I tend to use a messaging system, for example, the one provided by MVVM Light.

With a messaging system (using MVVM Light) you do something like this:

In your ViewModel:

private void SomeMethodThatNeedsToOpenADialog()
{
    Messenger.Default.Send(new OpenDialogXMessage());
}

And in your View:

Messenger.Default.Register<OpenDialogXMessage>(this, (msg) => {

    new DialogX().ShowDialog();
});

Some relevant links:

Community
  • 1
  • 1
Joao
  • 7,366
  • 4
  • 32
  • 48
  • +1 for the Messaging system approach, although I use [a simplified version of Prism's EventAggregator](http://rachel53461.wordpress.com/2011/10/09/simplifying-prisms-eventaggregator/) instead of MVVM light. The concept is the same - broadcast Messages from any ViewModel, and have your `App` class subscribe to receive those Messages and open/close the window specified in the Message properties. – Rachel Feb 14 '13 at 17:32
0

Well it's not a event handler solution, but how about a Binding solution? Unfortunately, you cannot bind Window.DialogResult, which causes the window to close, when the value is set. But you could create an AttachedProperty which can be bound to a property on the underlying ViewModel and sets the not bindable property, when its value is set. The AttachedProperty looks like this.

    public class AttachedProperties
    {
        public static readonly DependencyProperty DialogResultProperty =
            DependencyProperty.RegisterAttached("DialogResult", typeof (bool?), typeof (AttachedProperties), new PropertyMetadata(default(bool?), OnDialogResultChanged));

        private static void OnDialogResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var wnd = d as Window;
            if (wnd == null)
                return;

            wnd.DialogResult = (bool?) e.NewValue; //here the not bindable property is set and the windows is closed
        }

        public static bool? GetDialogResult(DependencyObject dp)
        {
            if (dp == null) throw new ArgumentNullException("dp");

            return (bool?)dp.GetValue(DialogResultProperty);
        }

        public static void SetDialogResult(DependencyObject dp, object value)
        {
            if (dp == null) throw new ArgumentNullException("dp");

            dp.SetValue(DialogResultProperty, value);
        }
    }

The AttachedProperty can be used like this


<Window x:Class="AC.Frontend.Controls.DialogControl.Dialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:hlp="clr-namespace:AC.Frontend.Helper"
        hlp:AttachedProperties.DialogResult="{Binding DialogResult}">
  <!-- put your content here -->
</Window>

Now you can use a Command to set the DialogResult property of the VM, which is the DataContext of the Window.

Kapitán Mlíko
  • 4,498
  • 3
  • 43
  • 60
DHN
  • 4,807
  • 3
  • 31
  • 45