Как переписать механизм диспетчеризации перенаправленных команд WPF - PullRequest
3 голосов
/ 13 июня 2009

Могу ли я расширить маршрутизацию команд 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");
        }
    }
}

1 Ответ

0 голосов
/ 27 июня 2009

Я смог решить эту проблему, используя метод Window.AddHandler, чтобы перехватить все перенаправленные события команды, а затем повторно вызвать их из textBlock1 следующим образом.

textBlock1.RaiseEvent (е);

У меня пока нет кода для этого, но идея в том, что перенаправленное событие, если оно не обработано, переходит в область видимости окна, где мы отлавливаем все необработанные события и повторно вызываем их из области главного окна

...