UserControl的Loaded事件未触发,EventTrigger没有响应。

13

我有一个包含以下事件触发器的用户控件:

<UserControl x:Class="TestApp.Views.MyUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         >

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <i:InvokeCommandAction Command="{Binding OnLoadedCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

这是通过UserControl的构造函数进行设置的(请忽略ServiceLocator..这只是一个快速原型):

public MyUserControl()
{
    InitializeComponent();

    DataContext = ServiceLocator.Current.GetInstance<DirectorySearchViewModel>();
}

在我的视图模型中,我有以下内容:

    public ICommand OnLoadedCommand { get; private set; }

    public MyUserControl()
    {
        OnLoadedCommand = new DelegateCommand(OnLoaded);
    }

    public void OnLoaded()
    {
    }

OnLoaded永远不会被调用。如果我将EventName更改为..MouseDown,则它可以工作,但它只是不能在Loaded中工作。

我很确定这是一个愚蠢的错误(我发誓过去已经做过无数次),但现在似乎无法弄清楚。


2
在这里提供一个建议,尝试在构造函数中调用InitializeComponent之前设置您的DC。 - user1228
BINGO。 - blue18hutthutt
2个回答

11
public MyUserControl()
{
    DataContext = ServiceLocator.Current.GetInstance<DirectorySearchViewModel>();
    InitializeComponent();
}

贵族们。


这个可行!你能说出为什么会发生这种情况吗?为什么 DataContext 需要先设置? - Abdulkarim Kanaan
1
@AbdulkarimKanaan 因为Loaded事件在调用InitializeComponent期间触发。InitializeComponent 初始化窗口。一旦它被初始化,Loaded事件就会触发。因为您在Loaded事件触发之后设置了DataContext,所以事件触发器没有任何东西可以触发,并且不记得事件已经触发,也不知道您希望在设置DataContext后触发它。这不是它的设计方式。 - user1228

3
对于其他需要此信息的人,您可以不使用代码后端来完成此操作:

<UserControl x:Class="TestApp.Views.MyUserControl"
    ... etc...
     x:Name="theControl"
     >

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction
                Command="{Binding ElementName=theControl, Path=OnLoadedCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

我在运行时得到了这个错误信息:"System.Windows.Data Error: 40 : BindingExpression path error: 'ViewLoadedCommand' property not found on 'object' ''FooView' (Name='self')'. BindingExpression:Path=ViewLoadedCommand; DataItem='FooView' (Name='self'); target element is 'InvokeCommandAction' (HashCode=21993383); target property is 'Command' (type 'ICommand')"。它在查找命令属性时查看的是视图而不是ViewModel。 - Dai
1
啊,看起来解决方案是使用 Command="{Binding ElementName=self, Path=DataContext.ViewLoadedCommand}" - 因此在 Path 中添加 "DataContext." 即可。 - Dai
哎呀,我甚至不记得回答这个问题了,但你绝对是正确的。对于这些类型的绑定,你必须在路径中指定DataContext。在我的测试中,我可能一直在使用控件作为它自己的DataContext。感谢纠正我的答案。 - Mark Feldman
2
如果(正如OP所述)在Loaded事件中DataContext尚未设置,则这并不能解决问题。 这基本上与问题中显示的代码完全相同。 - bitbonk

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