iv'e は CompositeCommand をスタートアップ プロジェクトでグローバルに公開しました
public static class Commands
{
public static readonly CompositeCommand DiceRolledCommand = new CompositeCommand();
}
私のスタートアップ プロジェクトで参照される ControlLibrary では、DelegateCommand を持つ Control を取得しました。この Control の各インスタンスは、グローバルに公開された DiceRolledCommand を使用して Command を登録する必要があります。
そうすることのベストプラクティスは何でしょう:
ここに 3 つのアイデアがありますが、最初の 2 つはハックのようなものであり、プログラミング コンポーネント (dp) を使用して変更し、コードとデザインが貧弱になるため、好きではありません。
1) DiceRolledCommand で設定され、その CallBack レジスタ MyControl の DelegateCommand (OnDiceRolledCommand) で設定されるタイプ CompositeCommand の通常のデカダンス プロパティ。
public class MyControl : Control
{
public DelegateCommand<Tuple<int, int>> OnDiceRolledCommand { get; private set; }
public CompositeCommand GlobalDiceRolledCommand
{
get { return (CompositeCommand)GetValue(GlobalDiceRolledCommandProperty); }
set { SetValue(GlobalDiceRolledCommandProperty, value); }
}
public static readonly DependencyProperty GlobalDiceRolledCommandProperty =
DependencyProperty.Register("GlobalDiceRolledCommand", typeof(CompositeCommand), typeof(MyControl), new UIPropertyMetadata(null,GlobalDiceRolledCommandPropertyChanged));
private static void GlobalDiceRolledCommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var myControl= d as MyControl ;
var compoisteCommand = e.NewValue as CompositeCommand;
compoisteCommand.RegisterCommand(myControl.OnDiceRolledCommand);
}
}
<local:MyControl GlobalDiceRolledCommand="{x:Static local:Commands.DiceRolledCommand}"/>
Dependency Property が使用される操作の一種であり、 Complex logical setter があるため、このアプローチは好きではありません。
2) 添付プロパティの CallBack に OnDiceRolledCommand を登録する添付プロパティを持つサードパーティ クラスを使用して、(1) と同じこともできます。
public static class Commands
{
public static readonly CompositeCommand DiceRolledCommand = new CompositeCommand();
public static ICommand GetRegisterToDiceRolledCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(RegisterToDiceRolledCommandProperty);
}
public static void SetRegisterToDiceRolledCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(RegisterToDiceRolledCommandProperty, value);
}
public static readonly DependencyProperty RegisterToDiceRolledCommandProperty =
DependencyProperty.RegisterAttached("RegisterToDiceRolledCommand", typeof(ICommand), typeof(Commands), new UIPropertyMetadata(null,OnRegisterToDiceRolledCommandProperty);
private static void OnRegisterToDiceRolledCommandProperty(DependencyObject d , DependencyPropertyChangedEventArgs e)
{
var commandToRegister = e.newValue as DelegateCommand;
DiceRolledCommand.RegisterCommand(commandToRegister );
}
}
<local:MyContorl local:Commands.RegisterToDiceRolledCommand="{Binding OnDiceRolledCommand , RelativeSource={RelativeSource Self}}"/>
私も1と同じ理由でこのアプローチが好きではありません..
3)複合コマンドをパラメーターとしてコンストラクターに渡します。コンストラクター内の初期化ロジックを本来あるべき場所に保持するため、このアプローチの方が優れています。XAML を介して契約者に引数を渡す方法がわかりません。それが可能かどうかさえわかりません。
public class MyControl : Control
{
public MyControl(CompositeCommand globalDiceRolledCommand)
{
.........
globalDiceRolledCommand.Register(OnDiceRolledCommand);
}
}
<local:MyControl ..... >
Some how pass parameters to contractor in order to create the element in XAML
</local:MyControl>
要約する :
A) (1) と (2) についての考え。
B) 3 をどのように達成するかについての考えと、それが良いデザインだと思われる場合。
C) このシナリオを達成するための適切なパターン。
前もって感謝します 。