XAML - Как иметь глобальные inputBindings? - PullRequest
6 голосов
/ 09 июля 2009

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

Чтобы определить локальные привязки ввода, я просто объявляю ввод в Window.InputBindings или UserControl.InputBindings.

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

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

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

РЕДАКТИРОВАТЬ: в своем ответе Кент 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 ]

9 голосов
/ 04 сентября 2009

Одним из решений является использование Присоединенного свойства с 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!"); }
    }
}
0 голосов
/ 09 июля 2009

Вы можете создать Style, который применяется ко всем вашим Window с. Что Style может установить InputBindings.

...