3

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) このシナリオを達成するための適切なパターン。

前もって感謝します 。

4

1 に答える 1

2

このようなグローバル コマンドを使用するときは、通常、すべてのライブラリが参照できるインフラストラクチャ クラス ライブラリのいずれかで定義されます。または、各モジュールが直接参照できる消費コア ライブラリで定義されます。

これについては、コード プロジェクトの記事の パート 2 (こちら) に多くのことを書きました。

于 2013-05-01T11:44:15.333 に答える