XAML - как иметь глобальные inputBindings?
у меня есть приложение WPF с несколькими окнами. Я хотел бы определить глобальные inputBindings.
чтобы определить локальные inputbindings, я просто объявляю ввод в окне.InputBindings или UserControl.InputBindings.
чтобы определить глобалы, я хотел бы сделать то же самое с классом приложения...
<Application
....>
<Application.InputBindings>
...
</Application.InputBindings>
Если у меня одна и та же привязка в 2 разных окнах, я должен закодировать ее дважды. Это не соответствует философии D. R. Y., И я думаю, что есть лучшее путь...
EDIT : в своем ответе Кент 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
все элементы управления данного типа в вашем приложении. К сожалению, так как вы не можете сделать "catch-all"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!"); }
}
}