【问题标题】:Using RoutedCommand in Main Window with User Controls在主窗口中使用带有用户控件的 RoutedCommand
【发布时间】:2017-02-18 15:17:37
【问题描述】:

我正在尝试了解路由命令的工作原理,但我遇到了一个问题。我创建了一个主窗口,其中包含 Button 和 ItemControl,并以 UserControls 作为其项目模板。

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

Thought 当我单击按钮时,它会在每个用户控件对象上触发方法,但遗憾的是这段代码不起作用 - 按钮被禁用。我错过了什么?

【问题讨论】:

    标签: c# wpf user-controls routed-commands


    【解决方案1】:

    Thought 当我单击按钮时,它会在每个用户控件对象上触发方法,但遗憾的是这段代码不起作用 - 按钮被禁用。我错过了什么?

    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 以及如何实现您的自定义 ICommand 或使用任何 MVVM 库中的通用实现。这是另一个故事,但请参阅以下博客文章以获得简要介绍:https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/

    MVVM 是在构建基于 XAML 的应用程序时推荐使用的设计模式,所有认真的 WPF 开发人员都应该学习它。

    【讨论】:

      【解决方案2】:

      您可以/应该将 ItemsControl 的 ItemsSource 作为 Button 的 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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多