用户控件如何判断自己是否可见

8

我在我的MainWindow中有一个如下所示的UserControl:

<ctrls:Login Visibility="{Binding DataContext.Vis,
                          RelativeSource={RelativeSource Mode=FindAncestor,
                                                          AncestorType=Window}},
                          Converter={StaticResource BooelanToVisibilityConverter}"/>

所以它的可见性与MainWindow的ViewModel中的属性Vis绑定。
我想知道的是,在UserControl的ViewModel中如何捕获可见性已更改的信号?当可见时,我希望开始一个计时器,并在隐藏时停止它。
1个回答

12

您可以在用户控件上挂钩UIElement.IsVisibleChanged事件:

<ctrls:Login IsVisibleChanged="Control_VisibleChanged"/>

后端代码:

private void Control_VisibleChanged(object sender, 
                                        DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue)
    {
       // Visible code here
    }
    else
    { 
       // Collapse code here
    }
 }

如果您想启动计时器,我认为在后台代码中执行没有任何问题。但是,如果您仍然希望在ViewModel中得到通知,您可以在UserControl ViewModel中创建一个ICommand,并使用交互触发器将其绑定到此事件。
<ctrls:Login>
   <i:Interaction.Triggers>
      <i:EventTrigger EventName="IsVisibleChanged">
          <i:InvokeCommandAction Command="{Binding VisibleChangedCommand}"/>
      </i:EventTrigger>
   </i:Interaction.Triggers>
</ctrls:Login>

如果交互触发对你来说是新的,请参考这篇文章


1
他希望在ViewModel中收到通知,而不是控件的代码后台。 - Alberto
1
e.NewValue 是一个布尔类型,而不是 Visibility 类型。你的代码应该显示 if ((bool)e.NewValue) { // IsVisible code here} ... - evanb
@RohitVats 我尝试了两种实现方式,我已经理解了第一种,但是在用户控件视图模型中的ICommand存在问题,你有这个工作示例吗? - Hank
你需要在项目中引用 Microsoft.Expression.Interactivity.Core 的 dll 才能使用它。可以参考这里的示例(http://coreclr.wordpress.com/2011/01/05/using-interaction-triggers-in-mvvm/)和这里的示例(http://www.danharman.net/2011/08/05/binding-wpf-events-to-mvvm-viewmodel-commands/),或者直接在谷歌上搜索 interaction triggers MVVM,会有很多相关的参考资料。 - Rohit Vats
这不会起作用,因为IsVisibleChanged是CLR事件,这在以下链接中已经有了答案: https://dev59.com/uVjUa4cB1Zd3GeqPTqwE 和: https://dev59.com/hXzaa4cB1Zd3GeqPRpKR - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接