原本以为这是一个很简单的问题,但是我却走了不少的弯路。记录下来自省。
我使用的是库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);