【问题标题】:Using interaction trigger to call visibility changed method WPF使用交互触发器调用可见性更改方法 WPF
【发布时间】:2014-02-17 02:40:07
【问题描述】:

我想弄清楚两件事,如何在用户控件的可见性更改时触发触发器,并将可见性的值作为参数传递。

无论出于何种原因,触发器似乎都没有触发。我刚刚添加了 ControlVisible 参数来显示我想要发生的事情,当测试它不存在时,只有一个消息框可以在可见性发生变化时捕获,就像在注释掉的方法中一样。

我在 Visual Studio 2010 中使用 4.0

包含用户控件的主窗口视图

<Window x:Class="bt.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:vm="clr-namespace:bt"
        xmlns:ctrls="clr-namespace:bt.Controls"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
        mc:Ignorable="d">

    <Grid>
        <ctrls:Login Visibility="{Binding DataContext.Vis,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window},Converter={StaticResource BooleanToVisibilityConverter}}" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="IsVisibleChanged">
                    <ei:CallMethodAction MethodName="VisibleTrigger" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ctrls:Login>
    </Grid>
</Window>

UserControl 视图模型:

namespace bt.Controls
{
    class LoginViewModel
    {
        public LoginViewModel()
        {
        }

        public void VisibleTrigger(bool ControlVisible)
        {
            if (ControlVisible)
            {
                MessageBox.Show("Start timer");
            }
            else
            {
                MessageBox.Show("Stop timer");
            }
        }

        //public void VisibleTrigger()
        //{
        //    MessageBox.Show("Changed");
        //}
    }
}

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    首先,我们需要将TargetObject属性设置为viewmodel/DataContext,因为要调用的方法在viewmodel中是可用的:

    ......
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="IsVisibleChanged">
            <ei:CallMethodAction MethodName="VisibleTrigger" TargetObject="{Binding}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    ......
    

    其次,EventTrigger 似乎不适用于 IsVisibleChanged 事件。所以上面的代码 sn-p 适用于其他事件,但不适用于 IsVisibleChanged。我们可以在this SO question 的答案中找到解决方法,通过使用 PropertyChangedTrigger 来监听 Visibility 属性更改,而不是监听 IsVisibleChanged 事件:

    <i:Interaction.Triggers>
        <ei:PropertyChangedTrigger Binding="{Binding Visibility, ElementName=MyControlName}">
            <ei:CallMethodAction  MethodName="VisibleTrigger" TargetObject="{Binding}"/>
        </ei:PropertyChangedTrigger>
    </i:Interaction.Triggers>
    

    第三,CallMethodAction 似乎没有提供将参数传递给方法的方法。为了能够调用带有参数的方法,我们最好使用 InvokeCommandAction 而不是 CallMethodAction,正如 here 的建议以及 @Rohit 在您的 previous question 中所建议的那样。

    【讨论】:

    • 没有 InvokeCommandAction 或者可以从 跳转到 并返回到 吗?
    • 没有尝试确定,但我认为没关系。你试过了吗?
    • 是的,它并没有失败,但它很难找到方法......没关系,实现了 ICommand 并且它有效,谢谢!
    猜你喜欢
    • 2010-10-29
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 2011-07-25
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多