RoutedCommands Executed和PreviewExecuted事件

时间:2011-01-12 15:43:10

标签: wpf routed-commands

我的问题是我想在多个地方处理命令。例如,我有自定义的UserControl,其中Button被绑定到某个命令。我在该控件中有一个命令绑定,但我在一个使用该控件的Window中也有一个命令绑定。

我的目标是在控件内执行一些操作,同时不中断窗口中命令的处理。

我尝试过尝试Executed和PreviewExecuted事件,但没有运气。然后我在一个窗口中模拟了问题(下面发布的代码)。

<Window x:Class="CommandingEvents.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:CommandingEvents="clr-namespace:CommandingEvents" 
    Title="Window1" Height="300" Width="300">
<Window.CommandBindings>
    <CommandBinding 
        Command="{x:Static CommandingEvents:Window1.Connect}"
        Executed="CommandBindingWindow_Executed"
        PreviewExecuted="CommandBindingWindow_PreviewExecuted"/>
</Window.CommandBindings>
<Grid>
    <Grid.CommandBindings>
        <CommandBinding 
        Command="{x:Static CommandingEvents:Window1.Connect}"
        Executed="CommandBindingGrid_Executed"
        PreviewExecuted="CommandBindingGrid_PreviewExecuted" />
    </Grid.CommandBindings>
    <Button Command="{x:Static CommandingEvents:Window1.Connect}" 
            CommandTarget="{Binding RelativeSource={RelativeSource Self}}"
            Content="Test" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>

namespace CommandingEvents
{
    public partial class Window1
    {
        public static readonly RoutedUICommand Connect = new
            RoutedUICommand("Connect", "Connect", typeof(Window1));

        public Window1()
        {
            InitializeComponent();
        }

        private void CommandBindingWindow_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Console.WriteLine("CommandBindingWindow_Executed");
            e.Handled = false;
        }

        private void CommandBindingGrid_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Console.WriteLine("CommandBindingGrid_Executed");
            e.Handled = false;
        }

        private void CommandBindingWindow_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            Console.WriteLine("CommandBindingWindow_PreviewExecuted");
            e.Handled = false;
        }

        private void CommandBindingGrid_PreviewExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            Console.WriteLine("CommandBindingGrid_PreviewExecuted");
            e.Handled = false;
        }
    }
}

当我点击按钮时,只打印出“CommandBindingWindow_PreviewExecuted”。这是为什么?我试图将e.Handled设置为false,但它没有任何区别。任何人都可以解释这种行为吗?

1 个答案:

答案 0 :(得分:9)

我不知道为什么会发生这种情况(以及它不是一个错误)但是这里写的是WPF wiki

  

有一个特殊性   CommandBinding是非常的   有趣且重要的是要知道。

     

CommandManager使用路由事件   通知不同的CommandBinding   命令执行的对象   调用(通过默认手势,   输入绑定,显式等)。

     

到目前为止,这是公平的   直截了当。然而,更重要的是   重要的是CommandBinding会   标记路由事件   CommandManager尽快处理   处理程序被执行(或者   PreviewExecuted或Executed)。

     

最后,即使你的处理程序有一个   与代表匹配的原型   叫做ExecutedRoutedEventHandler ,.   CommandBinding中执行的事件   不是RoutedEvent而是正常的CLR   事件。设置或离开   e.Handled flag to false将改变   什么都没有。

     

因此,只要执行或执行   调用PreviewExecuted处理程序,   RoutedCommand将停止它   路由。