当前位置:   article > 正文

MVVM下的窗口关闭_devexpress mvvm关闭窗口

devexpress mvvm关闭窗口

第一种:code_behind中调用Close方法

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

第二种:使用behavior

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

        

  1. <Button Content="_">
  2. <i:Interaction.Triggers>
  3. <i:EventTrigger EventName="Click">
  4. <i:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" PropertyName="WindowState" Value="{x:Static WindowState.Minimized}"/>
  5. </i:EventTrigger>
  6. </i:Interaction.Triggers>
  7. </Button>
  8. <Button Margin="5 0" Content="[ ]">
  9. <i:Interaction.Triggers>
  10. <i:EventTrigger EventName="Click">
  11. <i:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" PropertyName="WindowState" Value="{x:Static WindowState.Maximized}"/>
  12. </i:EventTrigger>
  13. </i:Interaction.Triggers>
  14. </Button>
  15. <Button Content="X" Background="LightCoral">
  16. <i:Interaction.Triggers>
  17. <i:EventTrigger EventName="Click">
  18. <!--用上这个可以在关闭前调用VM中的SaveData方法(普通方法就行)-->
  19. <i:CallMethodAction TargetObject="{Binding}" MethodName="SaveData"/>
  20. <i:CallMethodAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}}" MethodName="Close"/>
  21. </i:EventTrigger>
  22. </i:Interaction.Triggers>
  23. </Button>

        -- 通过反射,跑到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传过去

<Button Command="CloseCommand" CommandParameter="{Binding RelativeReSource={RelateiveResource AncestorType=Window}}">

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

  1. public interface ICloseWindow
  2. {
  3. void CloseWindow();
  4. }

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

第四步:对应的VM中的Command

  1. [RelayCommand]
  2. void Close(ICloseWindow window)
  3. {
  4. if (SaveData()) // 保存数据相关的方法
  5. {
  6. CloseWindow?.Invoke();
  7. }
  8. }

使用MvvmToolKit中的WeakReferenceMessenger

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

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

  1. WeakReferenceMessenger.Default.Register<CloseWindowMessage>(this, (_, m) =>
  2. {
  3. this.Close();
  4. });

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

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

++ 拓展:

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

注册:

  1. WeakReferenceMessenger.Default.Register<CloseWindowMessage>(this, (_, m) =>
  2. {
  3. if (m.Sender == this.DataContext)
  4. this.Close();
  5. });

发送消息:

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

++ 再改进:

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

然后变成:

注册:

  1. WeakReferenceMessenger.Default.Register<CloseWindowMessage>(this, (_, m) =>
  2. {
  3. if (m.Sender?.Target == this.DataContext)
  4. this.Close();
  5. });

发送消息:

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

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

VM构造方法中注册

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

        --SaveData方法的返回值是bool

在按钮的Click事件中调用

  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3. var response = WeakReferenceMessenger.Default.Send(new RequestMessage<bool>());
  4. if (response.Response)
  5. this.Close();
  6. }

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/数据挖掘灵魂/article/detail/60978
推荐阅读
相关标签
  

闽ICP备14008679号