使用 InvokeCommandAction 传递 Source 和 属性,而不使用 MultiBindings
Passing both Source and Property with InvokeCommandAction, without using MultiBindings
问题介绍
我在视图模型中的 属性 上绑定了 XAML,称为 "IsYoungerThanSeventy"。我正在使用 Prism 对事件 TargetUpdated
调用命令。目前我正在使用 TriggerParameterPath="Source"
.
传递 Source
(BinaryQuestion
)
问题
我不能同时通过 Source
和 Property
我想做什么
我还想将 Property
(IsYoungerThanSeventy
) 传递给同一命令。
最终我需要在一个函数中同时使用 Source
和 Property
来更新内容。
到目前为止我的代码
<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>
ICommand
接口的 Execute
方法只接受一个参数,因此为了能够传递两个值,您需要创建一个可以保存这两个值的类型,然后传递此类型的实例作为命令的命令参数。
最简单的方法是从视图的 code-behind 调用命令并在此处创建自定义类型的实例,例如:
<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 不是要从视图中删除代码,而是要分离关注点。
如果您出于某种奇怪的原因拒绝在 code-behind 中实现 view-related 行为,您将不得不将功能包装在自定义 InvokeCommandAction
class 中。您可以向此 class 添加属性以保存您的源和 属性 值,然后按照我在上面的示例代码中解释的那样调用命令。
你试过不传递参数吗?
<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;
}
您可以同时使用两者。
问题介绍
我在视图模型中的 属性 上绑定了 XAML,称为 "IsYoungerThanSeventy"。我正在使用 Prism 对事件 TargetUpdated
调用命令。目前我正在使用 TriggerParameterPath="Source"
.
Source
(BinaryQuestion
)
问题
我不能同时通过 Source
和 Property
我想做什么
我还想将 Property
(IsYoungerThanSeventy
) 传递给同一命令。
最终我需要在一个函数中同时使用 Source
和 Property
来更新内容。
到目前为止我的代码
<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>
ICommand
接口的 Execute
方法只接受一个参数,因此为了能够传递两个值,您需要创建一个可以保存这两个值的类型,然后传递此类型的实例作为命令的命令参数。
最简单的方法是从视图的 code-behind 调用命令并在此处创建自定义类型的实例,例如:
<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 不是要从视图中删除代码,而是要分离关注点。
如果您出于某种奇怪的原因拒绝在 code-behind 中实现 view-related 行为,您将不得不将功能包装在自定义 InvokeCommandAction
class 中。您可以向此 class 添加属性以保存您的源和 属性 值,然后按照我在上面的示例代码中解释的那样调用命令。
你试过不传递参数吗?
<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;
}
您可以同时使用两者。