【问题标题】:How to pass the sender and the arguments of event to the invoked command in ViewModel如何将事件的发送者和参数传递给 ViewModel 中调用的命令
【发布时间】:2017-04-29 14:03:49
【问题描述】:

在我的 UWP Windows 10 应用程序中,我想从事件和其他内容中清除我的代码隐藏并在 ViewModel 中执行所有操作,因此我使用 Core:InvokeCommandAction 在 VM 中调用命令,但我不知道如何将发送者和 Frame 对象的 Navigated 事件的参数传递给它

<Frame x:Name="MyFrame" SourcePageType="{Binding MainFramePageType, Mode=TwoWay}">
    <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="Navigated">
            <Core:InvokeCommandAction Command="{Binding MyFrameNavigatedCommand}" CommandParameter="{Binding ElementName=MyFrame}"/>            
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</Frame>

在虚拟机中:

public RelayCommand<object> MyFrameNavigatedCommand { get; private set; }

...
MyFrameNavigatedCommand = new RelayCommand<object>(MyNavigatedCommandExecuted);
...

private void MyNavigatedCommandExecuted(object sender)
{
    (sender as Frame).BackStack.Clear();
}

【问题讨论】:

    标签: xaml mvvm uwp windows-10 mvvm-light


    【解决方案1】:

    EventTriggerBehaviorEventArgs 对象传递给每个操作,因此对于InvokeCommandAction,您只需要绑定命令来接受命令实现中的参数。我不是 100% 熟悉 MVVMLight,但您可能正在使用某种“委托命令”实现;只要确保你的委托有一个参数,你就很好。

    如果你也需要sender 参数,那么这可能表明你不应该在视图模型中做任何你需要做的事情(直接访问/修改视图不是视图模型)。不过,如果您使用 x:Bind 将事件绑定到您的视图模型而不是 EventTriggerBehaviorx:Bind 需要周年更新 SDK),也可以传递 sender 参数。

    XAML

    <Frame x:Name="MyFrame"
           SourcePageType="{Binding MainFramePageType, Mode=TwoWay}"
           Navigated="{x:Bind Vm.Navigated}"/>
    

    背后的代码

    public MyViewModel Vm => (MyViewModel)DataContext;
    

    查看模型

    public void Navigated(object sender, NavigationEventArgs e)
    {
    }
    

    或者,您可以保留已有的内容,但只需在视图模型上公开一个 Frame 属性,您可以在页面后面的代码中设置该属性。

    根据您提供的代码,如果您只想在框架导航时清除框架的后退堆栈(或其他),那么您可以将其放入您自己的自定义行为或附加属性中以处理视图-而是具体的事情。

    【讨论】:

    • 我想通了发件人,但是如何传递事件参数呢?我还发现,如果您不指定 CommandParameter,则会发送 EventArgs。有没有办法同时发送发送者对象和事件参数?
    • 抱歉,由于某种原因,我错过了您问题的“发件人”部分。查看我的编辑。
    • 我需要最后一次澄清最佳实践。因此,将 CommandParameter 留空,将 EventArgs 传递给命令并将 Frame 添加到 CommandParameter 将对象传递给命令(如果需要)。自然地, InvokeCommandAction 并不意味着同时发送它们,所以我的问题是它们两个的最佳实践是什么(我想将 CommandParameter 留空,因为这很自然)就不将 ViewModel 暴露给 View 的逻辑而言,制作反图案。我认为在代码隐藏中包含一些事件逻辑并没有那么糟糕,如何决定什么?
    • 如果您不设置 CommandParameter,那么它将继承行为的值,对于 EventTriggerBehavior,该值将是事件的 EventArgs 对象。您只能将一件事传递给命令。 “正确”的方法是完全不按照我的建议将视图传递给视图模型。您是否考虑过使用 MVVMLight 的导航服务来代替您想要在这里做的事情?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2017-02-07
    • 2015-04-13
    相关资源
    最近更新 更多