在带有用户控件的 Main Window 中使用 RoutedCommand
Using RoutedCommand in Main Window with User Controls
我正在尝试了解路由命令的工作原理,但我遇到了问题。我创建了一个 Main Window,其中包含 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>
如果单击 Main Window 中的按钮,我想 运行 来自 ItemsControl 中每个 UserControl 的一些方法。
我已经在静态中创建了 RoutedCommand class:
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
}
以为当我单击按钮时它会在每个用户控件对象上触发方法,但遗憾的是这段代码不起作用 - 按钮被禁用。我错过了什么?
您 can/should 将 ItemsControl 的 ItemsSource
作为按钮的 CommandParameter 发送,然后对这些项目(模型)做任何您想做的事。通过适当的绑定,您可以在 UserControls(视图)中看到结果。举个例子:
假设这是 RoutedCommands:
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;
}
}
并将命令添加到您的应用程序中的CommandBindings
,例如:
public MainWindow()
{
InitializeComponent();
CommandBindings.Add(new CommandBinding(RoutedCommands.SendChangesCommand, RoutedCommands.ExecutedSendChangesCommand,RoutedCommands.CanExecuteSendChangesCommand));
}
您可以像这样绑定 Command 参数:
<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>
Thought It will fire method on every User Control object when I click the button, but sadly this code doesn't work - button is disabled. What am I missing?
A RoutedCommand
从目标元素搜索可视树,即调用命令的元素,在本例中是您的 Button
,
以及在其 CommandBindings
集合中具有匹配 CommandBinding
对象的元素,然后为该特定 CommandBinding
.
执行 Execute
委托
这里的问题是 ItemsControl
中的 UserControl
元素不是 Button
的可视父元素,因此永远不会调用该命令。
如果将 CommandBinding
移动到父级 Grid
,将启用 Button
:
<Grid>
<Grid.CommandBindings>
<CommandBinding Command="{x:Static local:RoutedCommands.SendChangesCommand}"
Executed="CommandBinding_Executed"/>
</Grid.CommandBindings>
<ItemsControl
...
如果您真的想在单击 Button
时对 UserControls
执行某些操作,则使用 RoutedCommand
不是执行此操作的方法。
相反,您应该查看 MVVM design pattern and how to implement your custom ICommand
or use a common implementation from any of the MVVM libraries out there. This is another story though but please refer to the following blog post for a brief introduction: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/。
MVVM 是 建议在构建基于 XAML 的应用程序时使用的设计模式,所有严肃的 WPF 开发人员都应该学习它。
我正在尝试了解路由命令的工作原理,但我遇到了问题。我创建了一个 Main Window,其中包含 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>
如果单击 Main Window 中的按钮,我想 运行 来自 ItemsControl 中每个 UserControl 的一些方法。
我已经在静态中创建了 RoutedCommand class:
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
}
以为当我单击按钮时它会在每个用户控件对象上触发方法,但遗憾的是这段代码不起作用 - 按钮被禁用。我错过了什么?
您 can/should 将 ItemsControl 的 ItemsSource
作为按钮的 CommandParameter 发送,然后对这些项目(模型)做任何您想做的事。通过适当的绑定,您可以在 UserControls(视图)中看到结果。举个例子:
假设这是 RoutedCommands:
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;
}
}
并将命令添加到您的应用程序中的CommandBindings
,例如:
public MainWindow()
{
InitializeComponent();
CommandBindings.Add(new CommandBinding(RoutedCommands.SendChangesCommand, RoutedCommands.ExecutedSendChangesCommand,RoutedCommands.CanExecuteSendChangesCommand));
}
您可以像这样绑定 Command 参数:
<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>
Thought It will fire method on every User Control object when I click the button, but sadly this code doesn't work - button is disabled. What am I missing?
A RoutedCommand
从目标元素搜索可视树,即调用命令的元素,在本例中是您的 Button
,
以及在其 CommandBindings
集合中具有匹配 CommandBinding
对象的元素,然后为该特定 CommandBinding
.
Execute
委托
这里的问题是 ItemsControl
中的 UserControl
元素不是 Button
的可视父元素,因此永远不会调用该命令。
如果将 CommandBinding
移动到父级 Grid
,将启用 Button
:
<Grid>
<Grid.CommandBindings>
<CommandBinding Command="{x:Static local:RoutedCommands.SendChangesCommand}"
Executed="CommandBinding_Executed"/>
</Grid.CommandBindings>
<ItemsControl
...
如果您真的想在单击 Button
时对 UserControls
执行某些操作,则使用 RoutedCommand
不是执行此操作的方法。
相反,您应该查看 MVVM design pattern and how to implement your custom ICommand
or use a common implementation from any of the MVVM libraries out there. This is another story though but please refer to the following blog post for a brief introduction: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/。
MVVM 是 建议在构建基于 XAML 的应用程序时使用的设计模式,所有严肃的 WPF 开发人员都应该学习它。