WPF MVVM 模式如何监听IsVisibleChanged 事件

server/2025/1/24 5:23:36/

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

我使用的是库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/server/160950.html

相关文章

代码随想录 栈与队列 test 7

347. 前 K 个高频元素 - 力扣&#xff08;LeetCode&#xff09; 首先想到哈希&#xff0c;用key来存元素&#xff0c;value来存出现次数&#xff0c;最后进行排序&#xff0c;时间复杂度约为o(nlogn)。由于只需求前k个&#xff0c;因此可以进行优化&#xff0c;利用堆来维护这…

npm install 报错:Command failed: git checkout 2.2.0-c

[TOC](npm install 报错&#xff1a;Command failed: git checkout 2.2.0-c) npm install 报错&#xff1a;Command failed: git checkout 2.2.0-c export NODE_HOME/usr/local/node-v14.14.0-linux-x64 npm config set registry https://registry.npmmirror.com 使用如上环…

Linux运维篇-PAM安全模块配置

PAM是什么&#xff1f; PAM&#xff08;可插入认证模块&#xff09;是UNIX操作系统上一个实现模块化的身份验证的服务。当程序需要对用户进行身份验证时加载并执行。PAM文件通常位于/etc/pam.d目录中。 而Linux-PAM&#xff0c;是linux可插拔认证模块&#xff0c;是一套可定制…

【Javaweb05】 XML探秘:解码数据的哲学,构建跨界的沟通桥梁

文章目录 前言&#x1f30d;一.XML简介❄️1.为什么需要 XML ❄️2.XML 技术用于解决什么问题❄️ 3.XML概念和特点 &#x1f30d;二.XML 语法❄️ 1、文档声明❄️ 2、元素❄️3、元素命名规则 ❄️ 4、属性❄️ 5、CDATA 区 &#x1f30d;三.XML 解析技术原理之DOM4j❄️ 1…

NIO 和 Netty 在 Spring Boot 中的集成与使用

Netty到底是个啥&#xff0c;有啥子作用 1. Netty 的本质&#xff1a;对 NIO 的封装 NIO 的原生问题&#xff1a; Java 的 NIO 提供了非阻塞 I/O 和多路复用机制&#xff0c;但其使用较为复杂&#xff08;如 Selector、Channel、Buffer 的配置和管理&#xff09;。开发者需要自…

PL/SQL语言的图形用户界面

PL/SQL语言的图形用户界面 引言 随着信息技术的迅猛发展&#xff0c;数据库系统在现代应用程序中的重要性愈加凸显。PL/SQL&#xff08;Procedural Language/Structured Query Language&#xff09;作为Oracle数据库的一种程序设计语言&#xff0c;以其强大的数据处理能力和高…

修改docker共享内存shm-size

法1&#xff1a;在创建容器时增加共享内存大小 nvidia-docker run -it -p 10000:22 --name"zm" -v /home/zm:/data ufoym/deepo:all-cu101 /bin/bash --shm-size20G法2&#xff1a;修改正在运行的容器的共享内存设置 查看容器、共享内存 docker ps -a df -lh | gr…

计算机网络 (51)鉴别

前言 计算机网络鉴别是信息安全领域中的一项关键技术&#xff0c;主要用于验证用户或信息的真实性&#xff0c;以及确保信息的完整性和来源的可靠性。 一、目的与重要性 鉴别的目的是验明用户或信息的正身&#xff0c;对实体声称的身份进行唯一识别&#xff0c;以便验证其访问请…