使用InvokeCommandAction传递Source和Property,而不使用MultiBindings

时间:2017-02-16 12:09:31

标签: c# wpf mvvm prism

问题简介

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

问题

我无法同时传递SourceProperty

我想做什么

我还想将PropertyIsYoungerThanSeventy)传递给同一个命令。

最终我需要在我正在调用的函数中更新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>

2 个答案:

答案 0 :(得分:1)

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

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

<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类中。您可以向此类添加包含源和属性值的属性,然后按照上面示例代码中的说明调用该命令。

答案 1 :(得分:0)

你试过没有参数?

<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;
}

你可以同时使用它们。