我正在尝试了解路由命令的工作原理,但我遇到了问题。我创建了一个带有Button和ItemControl的主窗口,其中UserControls作为其Item模板。
<Window>
<Grid>
<ItemsControl
ItemsSource="{Binding CollectionOfUsers}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<uc:UserUserControl
Name="{Binding PersonName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Button
Command="{x:Static helpers:RoutedCommands.SendChangesCommand}"
Content="SAVE"/>
</Grid>
</Window>
如果单击主窗口中的按钮,我想从ItemsControl中的每个UserControl运行一些方法。
我在静态类中创建了RoutedCommand:
public static class RoutedCommands
{
public static readonly RoutedCommand SendChangesCommand = new RoutedCommand();
}
将UserControl绑定到RoutedCommand。
<UserControl.CommandBindings>
<CommandBinding Command="{x:Static helpers:RoutedCommands.SendChangesCommand}"
Executed="CommandBinding_Executed"/>
使用代码隐藏方法:
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
// Do something
}
当我点击按钮时,它会在每个User Control对象上触发方法,但遗憾的是这段代码不起作用 - 按钮被禁用。我错过了什么?
答案 0 :(得分:0)
您可以/应该发送ItemsControl的public static class RoutedCommands
{
public static readonly RoutedCommand SendChangesCommand = new RoutedCommand();
public static void CanExecuteSendChangesCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
public static void ExecutedSendChangesCommand(object sender, ExecutedRoutedEventArgs e)
{
// Use e.Parameter;
}
}
作为Button的CommandParameter,并使用这些项目(模型)执行您喜欢的任何操作。使用正确的Bindings,您可以在UserControls(View)中查看结果。这是一个例子:
假设这是RoutedCommands:
CommandBindings
该命令将添加到应用程序中的 public MainWindow()
{
InitializeComponent();
CommandBindings.Add(new CommandBinding(RoutedCommands.SendChangesCommand, RoutedCommands.ExecutedSendChangesCommand,RoutedCommands.CanExecuteSendChangesCommand));
}
,例如:
<DockPanel>
<Button DockPanel.Dock="Top" Content="Click Me"
Command="{x:Static local:RoutedCommands.SendChangesCommand}"
CommandParameter="{Binding ElementName=ic, Path=ItemsSource}"/>
<ItemsControl Name="ic" ItemsSource="{Binding CollectionOfUsers}">
//...
</ItemsControl>
</DockPanel>
您可以使用以下内容绑定Command参数:
{{1}}
答案 1 :(得分:0)
当我点击按钮时,它会在每个User Control对象上触发方法,但遗憾的是这段代码不起作用 - 按钮被禁用。我错过了什么?
A RoutedCommand
从目标元素搜索可视树,即在这种情况下调用命令的元素Button
,
以及在CommandBinding
集合中具有匹配的CommandBindings
对象的元素,然后为此特定Execute
执行CommandBinding
委托。
这里的问题是UserControl
中的ItemsControl
元素不是Button
的可视父元素,因此永远不会调用该命令。
如果您将CommandBinding
移至父Grid
,则会启用Button
:
<Grid>
<Grid.CommandBindings>
<CommandBinding Command="{x:Static local:RoutedCommands.SendChangesCommand}"
Executed="CommandBinding_Executed"/>
</Grid.CommandBindings>
<ItemsControl
...
如果您真的想在点击UserControls
时对Button
执行某些操作,则使用RoutedCommand
不是这样做的方法。
相反,您应该查看MVVM design pattern以及如何实现自定义ICommand
或使用任何MVVM库中的通用实现。这是另一个故事,但请参阅以下博客文章以获得简要介绍:https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/。
MVVM是 推荐的设计模式,用于构建基于XAML的应用程序,所有认真的WPF开发人员都应该学习它。