WPF MVVM 模式如何监听IsVisibleChanged 事件

embedded/2025/1/24 17:33:39/

原本以为这是一个很简单的问题,但是我却走了不少的弯路。记录下来自省。

我使用的是库System.Windows.Interactivity.dll,首先在xaml 中使用了EventTrrigger 

<!--  当 IsVisibleChanged 事件触发时,执行绑定的命令  -->
<!--<i:EventTrigger EventName="IsVisibleChanged"><i:InvokeCommandAction Command="{Binding ElementName=MainGrid, Path=DataContext.IsVisibleChangedCommand}" /></i:EventTrigger></i:Interaction.Triggers>

但是发现是无效的。经过 改变IvokeCommandAction的参数,等方式,发现都无法触发。

最后决定使用behavior 来进行

接下来的写法如下

1、首先定义一个Behavior,

(注意:这里我也遇到了一个问题,原本我binding 的是Visibility 这个属性的,但是我也发现无法触发。通过测试发现,不是代码的问题。而是Visibility 从始至终都是Visibility.Visible ,但是IsVisible的属性,确实变化过的。这有点超乎我的认知。我认为这两个应该是同步的。所以最终attach 到IsVisible 的属性上)

    public class VisibilityMonitorBehavior : Behavior<UserControl>{// 定义一个 DependencyProperty 用于绑定 Visibility 属性public static readonly DependencyProperty VisibilityProperty =DependencyProperty.Register("IsVisible",typeof(bool),typeof(VisibilityMonitorBehavior),new PropertyMetadata(true, OnVisibilityChanged));private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){if (d is VisibilityMonitorBehavior behavior && behavior.AssociatedObject != null){var newVisibility = (bool)e.NewValue;if (newVisibility == true){(behavior.AssociatedObject.DataContext as UIViewModelBase).EnableTimer(true);}else{(behavior.AssociatedObject.DataContext as UIViewModelBase).EnableTimer(false);}LOG.Info($"{behavior.AssociatedObject.Name}Visibility changed to: {newVisibility}");}}public bool IsVisible{get => (bool)GetValue(VisibilityProperty);set => SetValue(VisibilityProperty, value);}// 关联控件时初始化绑定protected override void OnAttached(){base.OnAttached();if (AssociatedObject != null){// 绑定 AssociatedObject 的 Visibility 属性到行为的 VisibilityPropertyvar binding = new System.Windows.Data.Binding("IsVisible"){Source = AssociatedObject,Mode = System.Windows.Data.BindingMode.OneWay};BindingOperations.SetBinding(this, VisibilityProperty, binding);}}// 移除控件时清理资源protected override void OnDetaching(){BindingOperations.ClearBinding(this, VisibilityProperty);base.OnDetaching();}}

通过这种的方式,终于可以监听到IsVisibleChanged 事件了。 

值得记录的是,我需要动态添加这个behavior ,因此把这部分代码也贴出来。以供后期查看。

其中control就是控件

// 动态 添加 VisibilityMonitorBehaviorvar behaviors = Interaction.GetBehaviors(control);var visibilityBehavior = new VisibilityMonitorBehavior();behaviors.Add(visibilityBehavior);

 

 


http://www.ppmy.cn/embedded/156623.html

相关文章

HarmonyOS Next 应用UI生成工具介绍

背景 HarmonyOS Next适配开发过程中难买难要参考之前逻辑&#xff0c;但是可能时间较长文档不全&#xff0c;只能参考Android或iOS代码&#xff0c;有些逻辑较重的场景还可以通过AI工具将Android 的Java代码逻辑转成TS完成部分复用。对于一些UI场景只能手动去写&#xff0c;虽…

Excel-XLOOKUP-返回指定范围的数据

XLOOKUP(lookup_value, lookup_array, return_array, [if_not_found], [match_mode], [search_mode]) 第一参数lookup_value是必需参数&#xff0c;指定需要查询的值&#xff1b; 第二参数lookup_array是必需参数&#xff0c;指定查询的单元格区域或数组&#xff1b; 第三参数…

ChromeOS 132 版本更新

ChromeOS 132 版本更新 1. 企业定制化 Chrome Web Store 管理员现在可以使用新设置定制 Chrome Web Store 以适应他们管理的用户&#xff0c;包括以下功能&#xff1a; 添加公司标志添加首页横幅和自定义公告策划扩展集合实施基于类别的控制 这些设置可以通过管理员控制台进…

每日一题 414. 第三大的数

414. 第三大的数 简单 class Solution { public:int thirdMax(vector<int>& nums) {int n nums.size();long first , second,third;first second third LONG_MIN ;bool find false;for(auto num : nums){if(num > first){ third second;second first…

docker启动服务占用172.18网段怎么改成其他网段?和网桥有关吗?或者怎么改docker-compose启动用的yml文件

要修改 Docker 服务使用的网段(如从 172.18 改为其他网段),可以通过以下步骤实现: 1. 修改 Docker 默认网桥的网段 Docker 默认使用 docker0 网桥,其网段通常为 172.17.0.0/16。你可以通过修改 Docker 的配置文件来更改默认网段。 修改 Docker 配置文件 编辑 Docker 的…

【spring】集成JWT实现登录验证

在 Spring 应用中&#xff0c;使用 JSON Web Token (JWT) 是一种常见的认证和授权机制。JWT 是一种基于 JSON 的开放标准 (RFC 7519)&#xff0c;用来在各方之间传递安全、可信的数据。以下是如何在 Spring 框架中集成和使用 JWT 的完整指南。 核心概念 JWT 结构&#xff1a; H…

计算机视觉中的目标检测技术

1. 引言 目标检测是计算机视觉中的重要任务&#xff0c;涉及识别图像或视频中的多个对象并定位它们的位置。与图像分类不同&#xff0c;目标检测不仅需要识别类别&#xff0c;还要在图像中绘制出对象的边界框(Bounding Box)。本文将探讨目标检测的核心技术和应用&#xff0c;并…

c#配置config文件

1&#xff0c;引用命名空间 Configuration 及配置信息