WPF MVVM 模式如何监听IsVisibleChanged 事件

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

我使用的是库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 属性到行为的 VisibilityProperty
                var 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就是控件

复制代码
// 动态 添加 VisibilityMonitorBehavior
            var behaviors = Interaction.GetBehaviors(control);
            var visibilityBehavior = new VisibilityMonitorBehavior();
            behaviors.Add(visibilityBehavior);
相关推荐
听麟4 小时前
HarmonyOS 6.0+ 智慧出行导航APP开发实战:离线地图与多设备位置协同落地
华为·wpf·harmonyos
笨蛋不要掉眼泪12 小时前
Spring Boot + RedisTemplate 数据结构的基础操作
java·数据结构·spring boot·redis·wpf
LcVong1 天前
WPF MediaPlayer获取网络视频流当前帧并展示图片完整范例
网络·wpf
bugcome_com1 天前
WPF数据绑定入门:从传统事件到5种绑定模式
wpf
LateFrames2 天前
我用 WPF 做了一个 “苍蝇飞舞” 的屏保
ui·wpf
wuty0072 天前
完善基于WPF开发的标尺控件(含实例代码)
wpf·wpf标尺·支持横向竖向标尺·ruler
浩浩测试一下2 天前
洪水猛兽攻击 Ddos Dos cc Drdos floods区别
安全·web安全·网络安全·系统安全·wpf·可信计算技术·安全架构
无心水3 天前
分布式环境下定时任务与SELECT FOR UPDATE的陷阱与解决方案
分布式·后端·wpf·xxl-job·quartz·定时任务·selectforupdate
xdpcxq10293 天前
Spring AOP + Guava RateLimiter 用注解实现优雅限流
spring·wpf·guava
Aevget3 天前
界面控件DevExpress WPF v25.2新版亮点:模板工具包全新升级
wpf·界面控件·devexpress·ui开发·.net 10