2013-03-31 25 views
3

iv'e的最佳做法得到了在我的啓動項目iv'e引用的ControlLibrary在我的啓動項目WPF - 註冊DelegateCommand到CompositeCommand

public static class Commands 
{ 
     public static readonly CompositeCommand DiceRolledCommand = new CompositeCommand(); 
} 

全球暴露了一個控制一個CompositeCommand具有DelegateCommand, 該控件的每個實例都必須在全局公開的DiceRolledCommand中註冊它的Command。

什麼沃爾德是這樣做的最佳實踐:

這裏有3點想法的其中第2,我不喜歡,因爲他們是一個有點黑客,你需要一些編程組件(DP)和改變它的用途是爲了你的好處,導致代碼和設計不佳。


1)類型的CompositeCommand將與DiceRolledCommand 並在其上的回調寄存器MyControl的DelegateCommand(OnDiceRolledCommand)被設置 常規衰微屬性。

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}"/> 

,因爲它是一種操縱的,其中一個依賴屬性則採用了一個複雜的邏輯二傳手,我不喜歡這種方式。


2)我還可以做同樣的如(1)中使用第三方類具有附加屬性,這將註冊OnDiceRolledCommand在附加屬性的CallBack

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) PASSI ng複合命令作爲構造函數的參數,這種方法更好,因爲它保持構造函數中的初始化邏輯,它應該是,我只是不知道如何通過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)完成此場景的任何良好模式。

在此先感謝。

+0

?如果是這樣,那麼您可以通過XAML將參數傳遞給構造函數,否則不會。 http://msdn.microsoft.com/en-us/library/ee795382.aspx –

+0

不,我在.Net 4.0,感謝您的快速重播。 iv'e去註冊與附加屬性(2) –

回答

2

每當我使用這樣的全局命令時,它們通常在每個庫都可以引用的基礎架構類庫中定義。或者它們是在一個耗費的核心庫中定義的,每個模塊都可以直接引用。

我是您使用.NET 4.5寫了很多這件事在Code Project artical Part 2 here

+0

命令將標記爲答案,如果它有幫助。 – Jammer