UserControl中的RoutedCommand无法正常工作

时间:2019-05-26 16:20:52

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

我正试图根据乔希·史密斯(Josh Smith)的这篇文章,在我的RoutedCommands中使用UserControls

https://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/

我所做的与本文中的示例有些不同,并在Usercontrol中定义了RoutedCommand和CommandBindings。

现在我正尝试在MainWindow中使用它。因此,通过单击按钮,将执行UserControl中的命令。不幸的是,我得到的是一个禁用的按钮。

Foo_CanExecute()方法从不执行。

<UserControl x:Class="RoutedCommandTest.ViewControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:RoutedCommandTest"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.CommandBindings>
        <CommandBinding
            Command="{x:Static local:ViewControl.Foo}"
            PreviewCanExecute="Foo_CanExecute"
            PreviewExecuted="Foo_Executed"
        />
    </UserControl.CommandBindings>
    <Grid>

    </Grid>
</UserControl>

在ViewControl.xaml.cs

    public static readonly RoutedCommand Foo = new RoutedCommand();

    void Foo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    void Foo_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        MessageBox.Show("The Window is Fooing...");
    }

    public ViewControl()
    {
        InitializeComponent();
    }

在MainWindow.xaml中:

<Window x:Class="RoutedCommandTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:RoutedCommandTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <local:ViewControl/>
        <Button Content="Foo" Margin="0 5" Command="{x:Static local:ViewControl.Foo}"/>
    </Grid>
</Window>

1 个答案:

答案 0 :(得分:2)

您的命令位于用户控件中,而按钮位于主窗口中。

大概包含您的用户控件。

像冒泡事件和路由事件(用于驱动事件)。

Executed查找将可视树冒泡到绑定的命令。

PreviewExecuted查找将可视树向下绑定到绑定的命令。

由于您的按钮位于用户控件的父级中,所以我不确定是冒泡还是隧穿。

但是隧道将被PreviewExecute和PreviewCanExecute。

https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.commandbinding.previewexecuted?view=netframework-4.8

https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.commandbinding.previewcanexecute?view=netframework-4.8

正确执行路由命令可能很棘手。

有时候您需要做的一件事就是绑定commandtarget告诉它去哪里。

例如:

    <Grid>
      <local:UserControl1 x:Name="UC1" Height="60" Width="100"/>
      <Button Content="Foo" TextElement.FontSize="30" Command="{x:Static local:UserControl1.Foo}"
              CommandTarget="{Binding ElementName=UC1}"
              />
    </Grid> 

为我工作。

我很少发现它们有用-这是使它们不如您最初想象的有用的方面之一。