我是否可以以某种方式扩展WPF命令路由,以便首先检查是否可以在聚焦字段中调用命令,如果不在其他字段中调用(从不更改)?那有什么钩子吗?也许你不知道这是否会起作用,但在网上的某个地方看到类似的东西并且可以省去链接?
抽象示例
例如,如果我要编写带有侧面板的文本编辑器,面板就会有焦点。如果我按Ctrl + G,将调用一些命令,因为面板具有命令绑定和焦点(正常的WPF行为)。此外,如果我按Ctrl + H但此时间面板对调用的命令没有命令绑定。在这种情况下,我希望路由引擎切换到文本编辑器并将相同的命令鼓泡到那里。
真实示例
我有一个菜单项,表示粘贴,但焦点在侧面板上。如果我按下菜单命令binded to panel将被执行。假设没有适当的命令绑定到面板。在这种情况下,我想粘贴到文本编辑器中。
代码
此代码或多或少代表此方案。我想按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");
}
}
}
答案 0 :(得分:0)
我能够解决这个问题的方法是使用Window.AddHandler方法来捕获所有路由命令事件,然后像textBlock1那样重新引发它们。
textBlock1.RaiseEvent(E);
我还没有这方面的代码,但想法是如果没有处理的路由事件被冒泡到窗口范围,我们捕获所有未处理的事件并从主窗口区域重新提升它们