3

我可以以某种方式扩展 WPF 命令路由,以便它首先检查是否可以在焦点字段中调用命令,如果不能在其他字段中调用(从不更改)?有什么钩子吗?也许您不知道这是否可行,但在网上某处看到类似的东西并且可以保留链接?

抽象例子

例如,如果我要编写一个带有侧面板的文本编辑器,面板就会成为焦点。如果我按 Ctrl+G 将调用某些命令,因为面板具有命令绑定和焦点(即正常的 WPF 行为)。此外,如果我按 Ctrl+H 但这次面板没有调用命令的命令绑定。在这种情况下,我希望路由引擎切换到文本编辑器并在那里冒泡相同的命令。

真实例子

我有一个菜单项,上面写着粘贴,但焦点在侧面板上。如果我按下绑定到面板的菜单命令将被执行。假设没有适当的命令绑定到面板。在这种情况下,我想粘贴到文本编辑器中。

代码

这段代码或多或少代表了这种情况。我想按 Ctrl+H 并执行 CommandBinding_Executed_1

Window1.xaml

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1">
    <StackPanel>        
        <TextBox x:Name="textBlock1">
            <TextBox.CommandBindings>
                <CommandBinding Command="local:Window1.TestCommand" Executed="CommandBinding_Executed_1" />
                <CommandBinding Command="local:Window1.ForwardedTestCommand" Executed="CommandBinding_Executed_1" />
            </TextBox.CommandBindings>
        </TextBox>
        <TextBox x:Name="textBlock2">
            <TextBox.CommandBindings>
                <CommandBinding Command="local:Window1.TestCommand" Executed="CommandBinding_Executed_2" />
            </TextBox.CommandBindings>
            <TextBox.InputBindings>
                <KeyBinding Command="local:Window1.TestCommand" Gesture="Ctrl+G" />
                <KeyBinding Command="local:Window1.ForwardedTestCommand" Gesture="Ctrl+H" />
            </TextBox.InputBindings>
        </TextBox>
    </StackPanel>
</Window>

Window1.xaml.cs

using System.Windows;
using System.Windows.Input;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public static RoutedUICommand TestCommand = new RoutedUICommand("TestCommand", "TestCommand", typeof(Window1));
        public static RoutedUICommand ForwardedTestCommand = new RoutedUICommand("ForwardedTestCommand", "ForwardedTestCommand", typeof(Window1));

        public Window1()
        {
            InitializeComponent();
        }

        private void CommandBinding_Executed_1(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("CommandBinding_Executed_1");
        }

        private void CommandBinding_Executed_2(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("CommandBinding_Executed_2");
        }
    }
}
4

1 回答 1

0

我能够解决这个问题的方法是使用 Window.AddHandler 方法来捕获所有路由命令事件,然后像这样从 textBlock1 重新引发它们。

textBlock1.RaiseEvent(e);

我还没有代码,但想法是如果未处理路由事件,则会冒泡到窗口范围,我们会在其中捕获所有未处理的事件并从主窗口区域重新引发它们

于 2009-06-27T10:39:55.640 回答