Если вы попытаетесь определить CommandBindings
или InputBindings
как ресурсы в вашем App.xaml
, вы обнаружите, что вы не можете их использовать, поскольку XAML не позволяет вам использовать либо:
<Window ... CommandBindings="{StaticResource commandBindings}">
или для установки привязки команд с помощью установщика стиля:
<Setter Property="CommandBindings" Value="{StaticResource commandBindings}">
потому что ни одно из этих свойств не имеет метода доступа set. Используя идею в этом посте , я придумал чистый способ использования ресурсов из App.xaml
или любого другого словаря ресурсов.
Сначала вы определяете привязки команд и ввода косвенно, как и любой другой ресурс:
<InputBindingCollection x:Key="inputBindings">
<KeyBinding Command="Help" Key="H" Modifiers="Ctrl"/>
</InputBindingCollection>
<CommandBindingCollection x:Key="commandBindings">
<CommandBinding Command="Help" Executed="CommandBinding_Executed"/>
</CommandBindingCollection>
и затем вы ссылаетесь на них из XAML другого класса:
<Window ...>
<i:Interaction.Behaviors>
<local:CollectionSetterBehavior Property="InputBindings" Value="{StaticResource inputBindings}"/>
<local:CollectionSetterBehavior Property="CommandBindings" Value="{StaticResource commandBindings}"/>
</i:Interaction.Behaviors>
...
</Window>
CollectionSetterBehavior
- это повторно используемое поведение, которое не «устанавливает» свойство в его значение, а вместо этого очищает коллекцию и повторно заполняет ее. Таким образом, коллекция не меняется, только ее содержимое.
Вот источник поведения:
public class CollectionSetterBehavior : Behavior<FrameworkElement>
{
public string Property
{
get { return (string)GetValue(PropertyProperty); }
set { SetValue(PropertyProperty, value); }
}
public static readonly DependencyProperty PropertyProperty =
DependencyProperty.Register("Property", typeof(string), typeof(CollectionSetterBehavior), new UIPropertyMetadata(null));
public IList Value
{
get { return (IList)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(IList), typeof(CollectionSetterBehavior), new UIPropertyMetadata(null));
protected override void OnAttached()
{
var propertyInfo = AssociatedObject.GetType().GetProperty(Property);
var property = propertyInfo.GetGetMethod().Invoke(AssociatedObject, null) as IList;
property.Clear();
foreach (var item in Value) property.Add(item);
}
}
Если вы не знакомы с поведением, сначала добавьте это пространство имен:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
и добавьте соответствующую ссылку на ваш проект.