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"
対応する参照をプロジェクトに追加します。