How to Rewrite WPF Routed Dispatcher Commands

Can I extend the routing of WPF commands in such a way as to first check whether the command can be called in a focused field, and if not in some other (never changing)? Are there any hooks for this? Maybe you don’t know if this will work, but somewhere on the network is something similar and can save a link?

Abstract example

For example, if I were writing a text editor with a sidebar, and the panel would be focused. If I press Ctrl + G, some command will be called, because the panel has a command binding and focus (this is normal WPF behavior). Also, if I press Ctrl + H, but there is no binding command for the called command in this time bar. In this case, I would like the routing mechanism to switch to a text editor and apply the same command to it.

Real example

I have a menu item that says “Paste,” but the focus is on the sidebar. If I press the menu button attached to the panel, it will be executed. Suppose there is no corresponding command attached to the panel. In this case, I would like to insert into a text editor.

code

This code more or less represents this scenario. I would like to press Ctrl + H and execute 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");
        }
    }
}
+3
source share
1 answer

The way I was able to solve this was to use the Window.AddHandler method to catch all routed command events, and then re-raise them from textBlock1.

textBlock1.RaiseEvent (e);

I do not have code for this yet, but the idea is that the routed event, if it is not processed, bubbles up to the window area, where we catch all the unprocessed events and re-raise them from the main window area.

0
source

Source: https://habr.com/ru/post/1710381/


All Articles