XAML - Как иметь глобальные inputBindings?

У меня есть приложение WPF с несколькими окнами. Я хотел бы определить GLOBAL inputBindings.

Чтобы определить ЛОКАЛЬНЫЕ входные привязки, я просто объявляю ввод в Window.InputBindings или UserControl.InputBindings.

Чтобы определить GLOBAL, я бы хотел сделать то же самое с классом Application...

<Application
....>
<Application.InputBindings>
...
</Application.InputBindings>

Если у меня одна и та же привязка в 2 разных окнах, я должен дважды ее кодировать. Это не соответствует философии DRY, и я думаю, что есть лучший способ...

РЕДАКТИРОВАТЬ: в своем ответе Kent Boogaart советует мне использовать стиль. К сожалению, я не могу понять, как это определить. Это код:

 <Application.Resources>
    <Style TargetType="Window">
        <Setter Property="InputBindings">
            <Setter.Value>
                <Window.InputBindings>
                    <KeyBinding KeyGesture="Ctrl+M" Command="local:App.MsgCommand />
                </Window.InputBindings>
            </Setter.Value>
        </Setter>
    </Style>
</Application.Resources> 

Возникает ошибка: ошибка MC3080: Установщик свойства 'InputBindings' не может быть установлен, поскольку у него нет доступного средства доступа к множеству.

Мой стиль не так? Есть ли другое решение?

Есть идеи? Спасибо!

2 ответа

Решение

Одним из решений является использование присоединенного свойства с Style установить InputBindings на все элементы управления данного типа в вашем приложении. К сожалению, так как вы не можете сделать "ловушку" Style (что я знаю, в любом случае), вам придется создать Style для каждого типа элемента управления, на котором вы хотите установить InputBindings (однако, это не должно быть слишком много элементов управления). Ниже приведен пример кода, который показывает, как это сделать:

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

namespace WpfApplication1
{
    public class MyAttached
    {
        public static readonly DependencyProperty InputBindingsProperty =
            DependencyProperty.RegisterAttached("InputBindings", typeof(InputBindingCollection), typeof(MyAttached),
            new FrameworkPropertyMetadata(new InputBindingCollection(),
            (sender, e) =>
            {
                var element = sender as UIElement;
                if (element == null) return;
                element.InputBindings.Clear();
                element.InputBindings.AddRange((InputBindingCollection)e.NewValue);
            }));

        public static InputBindingCollection GetInputBindings(UIElement element)
        {
            return (InputBindingCollection)element.GetValue(InputBindingsProperty);
        }

        public static void SetInputBindings(UIElement element, InputBindingCollection inputBindings)
        {
            element.SetValue(InputBindingsProperty, inputBindings);
        }

    }
}

<Application x:Class="WpfApplication1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:loc="clr-namespace:WpfApplication1"
    StartupUri="Window1.xaml">
    <Application.Resources>
        <Style TargetType="TextBox">
            <Setter Property="loc:MyAttached.InputBindings">
                <Setter.Value>
                    <InputBindingCollection>
                        <KeyBinding Key="A" Modifiers="Ctrl" Command="loc:Window1.MyAction" />
                    </InputBindingCollection>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="Button">
            <Setter Property="loc:MyAttached.InputBindings">
                <Setter.Value>
                    <InputBindingCollection>
                        <KeyBinding Key="A" Modifiers="Ctrl" Command="loc:Window1.MyAction" />
                    </InputBindingCollection>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:loc="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="loc:Window1.MyAction" Executed="MyAction_Executed" />
    </Window.CommandBindings>
    <StackPanel>
        <Button Content="Try Ctrl+A Here!" />
        <TextBox Text="Try Ctrl+A Here!" />
    </StackPanel>
</Window>

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

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

        public Window1() { InitializeComponent(); }

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

Вы могли бы создать Style это относится ко всем вашим Windows. Тот Style мог бы установить InputBindings,

Другие вопросы по тегам