如何使一个通用的wpf mvvm窗口打开/关闭事件处理程序?

68de4m5k  于 2023-01-31  发布在  其他
关注(0)|答案(2)|浏览(324)

这是我当前的App.xaml.cs
它看起来简单的一两个,但我有7-8个窗口。有没有一个聪明的方法,使这一点更普遍和更好?

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();
}

...
vnzz0bqm

vnzz0bqm1#

太多的XAML代码隐藏是一个信号,表明您在某种程度上打破了MVVM模式。ViewModel接收EventArgs也是一个禁忌。
为了打开/关闭对话框,我倾向于使用消息传递系统,例如MVVM Light提供的消息传递系统。
使用消息传递系统(使用MVVM Light),您可以执行以下操作:
在视图模型中:

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

在您的视图中:

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

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

一些相关链接:

i7uaboj4

i7uaboj42#

这不是一个事件处理器的解决方案,但是Binding的解决方案怎么样?不幸的是,你不能绑定Window.DialogResult,这会导致窗口在设置值时关闭。但是你可以创建一个AttachedProperty,它可以绑定到底层ViewModel上的一个属性,并在设置值时设置不可绑定的属性。AttachedProperty看起来像这样。

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);
        }
    }

AttachedProperty可以这样使用

<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>

现在您可以使用Command设置VM的DialogResult属性,该属性是WindowDataContext

相关问题