【问题标题】:Passing both Source and Property with InvokeCommandAction, without using MultiBindings使用 InvokeCommandAction 传递 Source 和 Property,而不使用 MultiBindings
【发布时间】:2017-07-05 12:58:28
【问题描述】:

问题简介

我在视图模型中的一个属性上的 XAML 中有一个绑定,称为“IsYoungerThanSeventy”。 Iøm 使用 Prism 对事件 TargetUpdated 调用命令。目前我正在使用TriggerParameterPath="Source" 传递SourceBinaryQuestion)。

问题

我不能同时通过SourceProperty

我想做的事

我还想将Property (IsYoungerThanSeventy) 传递给同一命令。

最后,我在调用更新内容的函数中同时需要 SourceProperty

到目前为止我的代码

<wpfQuestionnaire:BinaryQuestion
    AnswerRequired="{Binding IsYoungerThanSeventy
        , Mode=TwoWay                                          
        , NotifyOnTargetUpdated=True}">

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="TargetUpdated">
            <prism:InvokeCommandAction 
                Command="{Binding PropertyBoundToAnswerRequiredChangedCommand}"
                TriggerParameterPath="Source"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</wpfQuestionnaire:BinaryQuestion>

【问题讨论】:

标签: c# wpf mvvm prism


【解决方案1】:

ICommand 接口的Execute 方法只接受一个参数,因此为了能够传递两个值,您需要创建一个可以保存这两个值的类型,然后将该类型的实例传递为命令的命令参数。

执行此操作的最简单方法是从视图的代码隐藏调用命令并在此处创建自定义类型的实例,例如:

<wpfQuestionnaire:BinaryQuestion
    AnswerRequired="{Binding IsYoungerThanSeventy
        , Mode=TwoWay                                          
        , NotifyOnTargetUpdated=True}" TargetUpdated="BinaryQuestion_TargetUpdated">
</wpfQuestionnaire:BinaryQuestion>

private void BinaryQuestion_TargetUpdated(object sender, DataTransferEventArgs e)
{
    BinaryQuestion bq = sender as BinaryQuestion;
    ViewModel vm = bq.DataContext as ViewModel;
    if (vm != null)
    {
        YourCustomCompositeCommandArgumentType param = new YourCustomCompositeCommandArgumentType() { Source = bq, Parameter = vm.IsYoungerThanSeventy };
        vm.PropertyBoundToAnswerRequiredChangedCommand.Execute(param);
    }
}

这不会破坏 MVVM 模式,因为您只是从相同的视图调用相同的命令。 MVVM 不是要从视图中消除代码,而是要分离关注点。

如果您出于某种奇怪的原因拒绝在代码隐藏中实现与视图相关的行为,则必须将功能包装在自定义 InvokeCommandAction 类中。你可以向这个类添加属性来保存你的源和属性值,然后按照我在上面的示例代码中解释的那样调用命令。

【讨论】:

  • 谢谢,这是我认为最优雅的解决方案。实际上我的问题有点错误。我实际上需要AnswerRequired 属性上的BindingExpressionResolvedSourcePropertyName。所以我用那个实现了你的解决方案。
【解决方案2】:

你试过不传递参数吗?

<i:Interaction.Triggers>
    <i:EventTrigger EventName="TargetUpdated">
        <prism:InvokeCommandAction 
            Command="{Binding PropertyBoundToAnswerRequiredChangedCommand}"
            />
    </i:EventTrigger>
</i:Interaction.Triggers>

那么你的命令就可以被声明了

PropertyBoundToAnswerRequiredChangedCommand = new DelegateCommand<DataTransferEventArgs>(OnPropertyBoundToAnswerRequiredChanged);

public void OnPropertyBoundToAnswerRequiredChanged(DataTransferEventArgs e){
var isYoungerThanSeventy = e.Property as bool;
var source = e.Source;
}

你可以同时使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-07
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    相关资源
    最近更新 更多