让我解释一下我的要求:
我有一个包含多个复选框的网格,如下所示:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<CheckBox>1</CheckBox>
<CheckBox
Grid.Column="1">2</CheckBox>
</Grid>
我清楚地知道如何使用mvvm light EventToCommand绑定到命令(在我的VM或其他任何地方定义)。 但是,众所周知,我有多个复选框。所以我必须这样做:
<CheckBox
Content="1">
<i:Interaction.Triggers>
<i:EventTrigger
EventName="Checked">
<ml:EventToCommand
Command="{Binding SomeCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
<CheckBox
Grid.Column="1"
Content="2">
<i:Interaction.Triggers>
<i:EventTrigger
EventName="Checked">
<ml:EventToCommand
Command="{Binding SomeCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
如果我有更多复选框,则必须一次又一次地执行C + V,以使每个复选框具有相同的EventToCommand行为。 更令人讨厌的是,我们还有另一个名为Unchecked的事件。通常,Checked和Uncheck的回调完全相同。所以我必须一次又一次地进行C + V ....
最后我的XAML漫长而复杂!
============================================= < / p>
我正在考虑这样的解决方法:
我查看了Checked以及Unchecked事件的源代码,发现它们都是RoutedEvent,其模式为Bubble,这意味着此路由事件调用bubble到达包含它们的网格。 所以我这样写了我的XAML代码:
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger
EventName="ToggleButton.Checked">
<ml:EventToCommand
Command="{Binding TestCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
......several check boxes......
</Grid>
但是上面的代码不起作用。选中事件和未选中都不是ATTACHED事件。
然后我删除了“ ToggleButton。”,就像这样:
<i:EventTrigger
EventName="Checked">
<ml:EventToCommand
Command="{Binding TestCommand}" />
</i:EventTrigger>
仍然无法正常工作! :(
事件应该在网格中冒泡,不是吗?
那么,有人对此有一些好的想法吗? 谢谢!
答案 0 :(得分:0)
您可以为Style
中的所有CheckBoxes
定义一个隐式Grid
:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="CheckBox">
<Setter Property="Command" Value="{Binding SomeCommand}" />
</Style>
</Grid.Resources>
<CheckBox>1</CheckBox>
<CheckBox Grid.Column="1">2</CheckBox>
</Grid>
您可以将每个Checked
的{{1}}属性绑定到源属性,而不是处理Unchecked
和IsChecked
事件:
CheckBox
答案 1 :(得分:0)
感谢您的建议。真的很方便。 我还发现了另一个解决方案,该解决方案发布在此站点上: link 在以上帖子中,提到了另一种解决方案:
using System;
using System.Windows;
using System.Windows.Interactivity;
namespace NaiveMepUi.GuiCommon
{
public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
{
public RoutedEventTrigger() { }
public RoutedEvent RoutedEvent { get; set; }
protected override void OnAttached()
{
Behavior behavior = base.AssociatedObject as Behavior;
FrameworkElement associatedElement =
base.AssociatedObject as FrameworkElement;
if (behavior != null)
{
associatedElement =
((IAttachedObject)behavior).AssociatedObject as FrameworkElement;
}
if (associatedElement == null)
{
throw new ArgumentException
("RoutedEventTrigger.AssociatedObject is not FrameworkElement.");
}
if (RoutedEvent != null)
{
associatedElement.AddHandler(
RoutedEvent,
new RoutedEventHandler(this.OnRoutedEvent));
}
}
/// <summary>
/// 路由事件被引发,继而引发基类的事件回调;
/// 但是这一步会丢弃<paramref name="sender"/>。
/// 如果事件绑定到命令,则命令只能接收到<paramref name="args"/>;
/// 作为在 ViewModel 中定义的命令,原则上不应该 View 中定义的元素。
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
void OnRoutedEvent(object sender, RoutedEventArgs args)
{
base.OnEvent(args);
}
protected override string GetEventName()
{
return RoutedEvent.Name;
}
}
}
然后我可以像这样在XAML中使用它:
<Grid>
<i:Interaction.Triggers>
<guicommon:RoutedEventTrigger
RoutedEvent="CheckBox.Checked">
<ml:EventToCommand
Command="{Binding }" />
<!--todo 测试一下这种设计模式是否可行-->
</guicommon:RoutedEventTrigger>
</i:Interaction.Triggers>
</Grid>