wpf-将DelegateCommand注册到CompositeCommand的最佳实践 [英] wpf - best practice of registering a DelegateCommand to a CompositeCommand

查看:260
本文介绍了wpf-将DelegateCommand注册到CompositeCommand的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的启动项目中,iv'e在全球公开了一个CompositeCommand

iv'e got a CompositeCommand exposed globally in my startup project

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

在我的启动项目iv引用的ControlLibrary中,有一个控件具有一个DelegateCommand,此控件的每个实例
必须向全局公开的DiceRolledCommand注册其Command。

in a ControlLibrary referenced by my startup project iv'e got a Control which has a DelegateCommand , each instance of this Control has to register it's Command with the globally exposed DiceRolledCommand.

这样做的最佳实践是什么:

what wold be the best practice of doing so :

这是3个想法,其中前2个是不喜欢,因为它们是一种黑客,您需要使用一些编程组件(dp)并对其进行更改以使自己受益,从而导致代码和设计不佳。

here are 3 idea's of which the first 2 i don't like because they are a kinda of hack , where you take some programming component (dp) and alter it's use for your benefit , resulting in poor code and design .

1)
a CompositeCommand类型的常规衰退属性,将使用DiceRolledCommand
进行设置,并在其CallBack上注册MyControl的DelegateCommand(OnDiceRolledCommand )。

1) a regular decadency property of type CompositeCommand which will be set with DiceRolledCommand and on it's CallBack register MyControl's 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}"/>

我不喜欢这种方法,因为这是一种使用依赖项属性的操作复杂的逻辑设置器。

i don't like this approach since it's a kind of manipulation where a Dependency Property is used has a Complex logical setter .

2)我也可以使用第三方做与(1)中相同的操作带有附加属性的类,它将在附加属性的CallBack中注册OnDiceRolledCommand

2) i could also do the same as in (1) using a third party class with an attached property which will register the OnDiceRolledCommand in an attached property's 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 ..

i also don't like this approach for the same reason as 1 ..

3)将复合命令作为参数传递给构造函数,这种方法更好,因为它可以使
在应该在构造函数中初始化逻辑的地方,我只是想不通如何通过XAML将参数
传递给承包商,我不确定是否可行。

3) passing the composite command as a parameter to constructor , this approach is better since it keeps the initializing logic in the constructor where it should be , i just can't figure out how to pass an argument to a contractor through XAML , i'm not sure if it's even possible .

 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)的想法。

A) any thoughts about (1) and (2) .

B)考虑如何完成3,以及是否设计得不错。

B) thoughts of how to accomplish 3 , and if it seems like good design .

C)完成此方案的任何良好模式。

C) Any good pattern of accomplishing this scenario.

提前感谢。

推荐答案

每当我使用全局命令时,它们通常都在每个库都可以引用的基础结构类库中定义。或者在一个消耗性的核心库中定义它们,每个模块都可以直接引用它们。

Whenever I use Global Commands like that they are usually defined in either an Infrastructure class library which every library can reference. Or they are defined in a consuming core library that each module could reference directly.

我在代码项目文章
此处的第2部分

这篇关于wpf-将DelegateCommand注册到CompositeCommand的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆