MVVM下的窗口关闭

第一种:code_behind中调用Close方法

        很明显这个处理并不是很好

第二种:使用behavior

        如果是简单的关闭窗口,这样还是ok的

        



        -- 通过反射,跑到Window中调用Close方法,或者修改WindowState

        中间那颗按钮想要实现再点击一次实现窗口正常大小就有点复杂

        并且如果需要在关闭窗口前保存好数据的方法SaveData是有返回参数的,这样就不是很好了

第三种:委托绑定关闭窗口,普通Command

在VM中设置关闭窗口的委托,可以是Action;通过Command进行激活,可以在激活之前调用DataSave对数据进行保存。

View中绑好这个Command,code_behind中将VM中的Action绑定上this.Close()方法

第四种:将Window传给VM

参考:WPF传递任意控件或任意控件的属性给ViewModel_wpf绑定viewmodel的方法 并且传递一个name指定的控件实例-CSDN博客

显然如果直接将整个Window传给VM中的Command那肯定是不太好的,这个时候可以借助接口传过去。

第一步:将Window传过去

第二步:创建带有关闭窗口的接口

public interface ICloseWindow
{
    void CloseWindow();
}

第三步:让View的code_behind接上这个接口并实现方法,方法的内容就是调用Close()方法关闭窗口

第四步:对应的VM中的Command

[RelayCommand]
void Close(ICloseWindow window)
{
    if (SaveData()) // 保存数据相关的方法
    {
        CloseWindow?.Invoke();
    }
}

使用MvvmToolKit中的WeakReferenceMessenger

第一步:首先注册一个类,这里是CloseWindowMessage,这个类什么都不用动,作用应该仅仅是标记同一个消息,方便调用

第二步:被调用(样例是code_behind中的关闭)

WeakReferenceMessenger.Default.Register(this, (_, m) =>
{
    this.Close();
});

第三步:调用(样例是VM中Command调用)

 WeakReferenceMessenger.Default.Send(new CloseWindowMessage());

++ 拓展:

        可以往CloseWindowMessage中添加属性public object? Sender {  get; set; },方便判断这个消息是谁注册的

注册:

WeakReferenceMessenger.Default.Register(this, (_, m) =>
{
    if (m.Sender == this.DataContext)
        this.Close();
});

发送消息:

WeakReferenceMessenger.Default.Send(new CloseWindowMessage { Sender = this}); 

++ 再改进:

但是这样又有不好的地方,这个引用印象到GC的释放;因此可以将CloseWindowMessage类中的object属性改为public WeakReference? Sender {  get; set; }

然后变成:

注册:

WeakReferenceMessenger.Default.Register(this, (_, m) =>
{
    if (m.Sender?.Target == this.DataContext)
        this.Close();
});

发送消息:

WeakReferenceMessenger.Default.Send(new CloseWindowMessage { Sender = new WeakReference(this)}); 

-----------甚至可以反过来-------------------------------

VM构造方法中注册

WeakReferenceMessenger.Default.Register>(this, (object _, RequestMessage m) => m.Reply(SaveData()));

        --SaveData方法的返回值是bool

在按钮的Click事件中调用

private void Button_Click(object sender, RoutedEventArgs e)
{
    var response = WeakReferenceMessenger.Default.Send(new RequestMessage());
    if (response.Response) 
        this.Close();
}

学麻了,要多练习才能记得住

你可能感兴趣的:(C#,wpf,wpf,c#,windows)