麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

C#:WinForm之Command

2019-11-14 13:38:24
字體:
來源:轉載
供稿:網友

  本文主要介紹WinForm項目中如何像WPF一樣優雅的使用Command來實現業務操作。想必大家已經疲于雙擊控件生成事件處理方法來實現業務操作,如多控件(按鈕、菜單、工具條、狀態欄等命令控件)來做同一個動作,還要控制它們啟用(Enabled)狀態等等,使代碼結構冗長且可讀性差。下面具體介紹和實現WinForm中對Command的應用。

  1. 命令(Command)

    顧 名思義,定義一個命令,繼承至System.Windows.Input.ICommand接口,實現 Execute(object) ,CanExecute(object)方法和 CanExecuteChanged事件。由 CanExecute 確定是否調用 Execute 執行該命令。

     1     /// <summary> 2     /// 定義一個執行的命令。 3     /// </summary> 4     public abstract class Command : ICommand 5     { 6         /// <summary> 7         /// The can executable 8         /// </summary> 9         PRivate bool canExecutable = true;10 11         /// <summary>12         /// 當出現影響是否應執行該命令的更改時發生。13         /// </summary>14         public event EventHandler CanExecuteChanged;15 16         /// <summary>17         /// 定義用于確定此命令是否可以在其當前狀態下執行的方法。18         /// </summary>19         /// <param name="parameter">此命令使用的數據。 如果此命令不需要傳遞數據,則該對象可以設置為 null。</param>20         /// <returns>如果可以執行此命令,則為 true;否則為 false。</returns>21         public abstract bool CanExecute(object parameter);22 23         /// <summary>24         /// 定義在調用此命令時調用的方法。25         /// </summary>26         /// <param name="parameter">此命令使用的數據。 如果此命令不需要傳遞數據,則該對象可以設置為 null。</param>27         public abstract void Execute(object parameter);28 29 30         /// <summary>31         /// 提升命令狀態更改。32         /// </summary>33         /// <param name="parameter">The parameter.</param>34         internal protected void RaiseCommandState(object parameter)35         {36             var able = CanExecute(parameter);37             if (able != canExecutable)38             {39                 canExecutable = able;40                 OnCanExecuteChanged(EventArgs.Empty);41             }42         }43 44         /// <summary>45         /// 觸發當命令狀態更改事件。46         /// </summary>47         /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>48         protected virtual void OnCanExecuteChanged(EventArgs e)49         {50             if (CanExecuteChanged != null)51             {52                 CanExecuteChanged(this, e);53             }54         }55     }
    Command 代碼
  2. 命令參數(CommandParameter)

    提供給命令執行時的參數,該對象主要由參數源(Source)和參數源的屬性(Parameter)構成。參數源可繼承至System.ComponentModels.INotifyPropertyChanged接口,實現屬性值更改通知。此 Parameter 必須為屬性(也可以是靜態屬性)。

      1     /// <summary>  2     /// 表示命令參數。  3     /// </summary>  4     public sealed class CommandParameter  5     {  6         private readonly Type sourceType;  7         private readonly object source;  8         private readonly string propertyMember;  9  10         private readonly bool booleanOppose = false; 11         private Command command; 12  13         /// <summary> 14         /// 獲取一個值,該值表示命令參數源。 15         /// </summary> 16         /// <value>The source.</value> 17         public object Source 18         { 19             get { return source; } 20         } 21  22         /// <summary> 23         /// 獲取一個值,該值表示命令參數的類型若當前非靜態類型綁定則為 Source 類型。 24         /// </summary> 25         /// <value>The type of the source.</value> 26         public Type SourceType 27         { 28             get 29             { 30                 return sourceType; 31             } 32         } 33  34         /// <summary> 35         /// 獲取一個值,該值表示命令執行參數。 36         /// </summary> 37         /// <value>The parameter.</value> 38         public object Parameter { get { return ResolvePropertyValue(); } } 39  40         /// <summary> 41         /// 獲取一個值,該值表示參數所屬的命令。 42         /// </summary> 43         /// <value>The command.</value> 44         public Command Command 45         { 46             get 47             { 48                 return command; 49             } 50             internal set 51             { 52                 if (value != command) 53                 { 54                     command = value; 55                     command.RaiseCommandState(Parameter); 56                 } 57             } 58         } 59  60         /// <summary> 61         /// 初始化 RelateCommandParameter 新實例。 62         /// </summary> 63         /// <param name="source">綁定源。</param> 64         /// <param name="propertyMember">綁定成員(屬性名稱)。</param> 65         /// <param name="booleanOppose">若值為System.Boolean時,是否取反。</param> 66         public CommandParameter(object source, string propertyMember, bool booleanOppose = false) 67         { 68             this.source = source; 69             this.sourceType = source.GetType(); 70             this.propertyMember = propertyMember; 71             this.booleanOppose = booleanOppose; 72             BindNotifyObject(source); 73         } 74  75         /// <summary> 76         /// 初始化 RelateCommandParameter 新實例。 77         /// </summary> 78         /// <param name="source">綁定源。</param> 79         /// <param name="propertyMember">綁定成員(屬性名稱)。</param> 80         /// <param name="booleanOppose">若值為System.Boolean時,是否取反。</param> 81         public CommandParameter(object source, Expression<Func<string>> propertyMember, bool booleanOppose = false) 82             : this(source, ResolvePropertyName(propertyMember), booleanOppose) 83         { 84  85         } 86  87         /// <summary> 88         /// 初始化一個可指定靜態成員的 RelateCommandParameter 新實例。 89         /// </summary> 90         /// <param name="staticSourceType">靜態類類型。</param> 91         /// <param name="propertyMember">綁定成員(屬性名稱)。</param> 92         /// <param name="booleanOppose">若值為System.Boolean時,是否取反。</param> 93         public CommandParameter(Type staticSourceType, string propertyMember, bool booleanOppose = false) 94         { 95             this.sourceType = staticSourceType; 96             this.propertyMember = propertyMember; 97             this.booleanOppose = booleanOppose; 98         } 99 100         private void BindNotifyObject(object source)101         {102             if (typeof(INotifyPropertyChanged).IsAssignableFrom(source.GetType()))103             {104                 ((INotifyPropertyChanged)source).PropertyChanged += SourcePropertyChanged;105             }106         }107 108         private void SourcePropertyChanged(object sender, PropertyChangedEventArgs e)109         {110             if (e.PropertyName == propertyMember)111             {112                 if (Command != null)113                 {114                     Command.RaiseCommandState(Parameter);115                 }116             }117         }118 119         private object ResolvePropertyValue()120         {121             var flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic;122             if (source == null)123             {124                 flags |= System.Reflection.BindingFlags.Static;125             }126             else127             {128                 flags |= System.Reflection.BindingFlags.Instance;129             }130 131             var pro = sourceType.GetProperty(propertyMember, flags);132             if (pro == null)133             {134                 throw new MemberaccessException(string.Format("Not found {2} member /"{0}/" in /"{1}/"", propertyMember, sourceType, source == null ? "static" : "instance"));135             }136             if (Type.GetTypeCode(pro.PropertyType) == TypeCode.Boolean)137             {138                 if (booleanOppose)139                 {140                     return !((Boolean)pro.GetValue(source));141                 }142             }143             return pro.GetValue(source);144         }145 146         private static string ResolvePropertyName(Expression<Func<string>> propertyMember)147         {148             if (propertyMember != null)149             {150                 return ((MemberExpression)propertyMember.Body).Member.Name;151             }152             else153             {154                 throw new ArgumentNullException("propertyMember");155             }156         }157     }
    CommandParameter 代碼
  3. 命令綁定(CommandBinding)

    命令和命令參數組合構建成一個綁定對象。

     1     /// <summary> 2     /// 定義命令綁定對象。 3     /// </summary> 4     public sealed class CommandBinding 5     { 6         /// <summary> 7         /// 獲取一個值,該值表示命令綁定的對象。 8         /// </summary> 9         /// <value>The command.</value>10         public Command Command { get; private set; }11 12         /// <summary>13         /// 獲取一個值,該值表示命令執行參數。14         /// </summary>15         /// <value>The command parameter.</value>16         public CommandParameter CommandParameter { get; private set; }17 18         /// <summary>19         /// 初始化 <see cref="CommandBinding"/> 新實例。20         /// </summary>21         /// <param name="command">要綁定的命令。</param>22         public CommandBinding(Command command)23             : this(command, null)24         {25 26         }27 28         /// <summary>29         /// 初始化 <see cref="CommandBinding"/> 新實例。30         /// </summary>31         /// <param name="command">要綁定的命令。</param>32         /// <param name="commandParameter">要綁定的命令參數。</param>33         public CommandBinding(Command command, CommandParameter commandParameter)34         {35             this.Command = command;36             this.CommandParameter = commandParameter;37             if (this.CommandParameter != null)38             {39                 this.CommandParameter.Command = this.Command;40             }41         }42 43         /// <summary>44         /// 初始化 <see cref="CommandBinding"/> 新實例。45         /// </summary>46         /// <param name="command">要綁定的命令。</param>47         /// <param name="source">要綁定的命令參數的實例。</param>48         /// <param name="propertyMember">要綁定的命令參數的屬性名稱。</param>49         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param>50         public CommandBinding(Command command, object source, string propertyMember, bool booleanOppose = false)51             : this(command, CreateCommandParameter(source, propertyMember, booleanOppose))52         {53 54         }55 56         /// <summary>57         /// 初始化 <see cref="CommandBinding"/> 新實例。58         /// </summary>59         /// <param name="command">要綁定的命令。</param>60         /// <param name="staticSourceType">靜態類類型。</param>61         /// <param name="propertyMember">綁定成員(屬性名稱)。</param>62         /// <param name="booleanOppose">若值為System.Boolean時,是否取反。</param>63         public CommandBinding(Command command, Type staticSourceType, string propertyMember, bool booleanOppose = false)64             : this(command, new CommandParameter(staticSourceType, propertyMember, booleanOppose))65         {66         }67 68         private static CommandParameter CreateCommandParameter(object source, string propertyMember, bool booleanOppose = false)69         {70             return new CommandParameter(source, propertyMember, booleanOppose);71         } 72     }
    CommandBinding 代碼
  4. 命令目標(CommandTarget)

    此為最終執行命令的目標,構建此對象實例時指定一個綁定(CommandBinding),監視WinForm命令控件(如Control、ToolStripItem)等包含 Click 事件和 Enabled 屬性的對象。

      1     /// <summary>  2     /// 表示命令綁定的執行目標。  3     /// </summary>  4     public sealed class CommandTarget : IDisposable  5     {  6         private readonly object target;  7         private bool disposed = false;  8   9         /// <summary> 10         /// 獲取一個值,該值表示目標是否已釋放。 11         /// </summary> 12         /// <value><c>true</c> if disposed; otherwise, <c>false</c>.</value> 13         public bool Disposed { get { return disposed; } } 14  15         /// <summary> 16         /// 獲取一個值,該值表示目標的命令綁定源。 17         /// </summary> 18         /// <value>The command binding.</value> 19         public CommandBinding CommandBinding { get; private set; } 20  21         /// <summary> 22         /// 初始化 CommandTarget 新實例。 23         /// </summary>  24         /// <param name="binding">命令綁定源。</param> 25         private CommandTarget(CommandBinding binding) 26         { 27             CommandBinding = binding; 28             CommandBinding.Command.CanExecuteChanged += CommandStateChanged; 29         } 30  31  32         /// <summary> 33         /// 初始化 CommandTarget 新實例。 34         /// </summary> 35         /// <param name="control">綁定目標。</param> 36         /// <param name="commandBinding">命令綁定源。</param> 37         public CommandTarget(Control control, CommandBinding commandBinding) 38             : this(commandBinding) 39         { 40             target = control; 41             control.Click += OnClick; 42             var parameter = GetParameterValue(); 43             control.Enabled = commandBinding.Command.CanExecute(parameter); 44         } 45  46         /// <summary> 47         /// 初始化 CommandTarget 新實例。 48         /// </summary> 49         /// <param name="item">綁定目標。</param> 50         /// <param name="commandBinding">命令綁定源。</param> 51         public CommandTarget(ToolStripItem item, CommandBinding commandBinding) 52             : this(commandBinding) 53         { 54             target = item; 55             item.Click += OnClick; 56             var parameter = GetParameterValue(); 57             item.Enabled = commandBinding.Command.CanExecute(parameter); 58         } 59  60  61         /// <summary> 62         /// Handles the <see cref="E:Click" /> event. 63         /// </summary> 64         /// <param name="sender">The sender.</param> 65         /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> 66         private void OnClick(object sender, EventArgs e) 67         { 68             object parameter = null; 69             if (CommandBinding.CommandParameter != null) 70             { 71                 parameter = CommandBinding.CommandParameter.Parameter; 72             } 73             var command = CommandBinding.Command; 74             if (command.CanExecute(parameter)) 75             { 76                 command.Execute(parameter); 77             } 78         } 79         /// <summary> 80         /// Commands the state changed. 81         /// </summary> 82         /// <param name="sender">The sender.</param> 83         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> 84         private void CommandStateChanged(object sender, EventArgs e) 85         { 86             var property = target.GetType().GetProperty("Enabled"); 87             if (property != null) 88             { 89                 var parameter = GetParameterValue(); 90                 var enable = CommandBinding.Command.CanExecute(parameter); 91                 property.SetValue(target, enable); 92             } 93         } 94  95         private object GetParameterValue() 96         { 97             if (CommandBinding.CommandParameter == null) 98             { 99                 return null;100             }101             return CommandBinding.CommandParameter.Parameter;102         }103 104         /// <summary>105         /// 執行與釋放或重置非托管資源相關的應用程序定義的任務。106         /// </summary>107         public void Dispose()108         {109             if (disposed)110             {111                 return;112             }113             disposed = true;114             CommandBindingManager.Unregister(this);115             CommandBinding.Command.CanExecuteChanged -= CommandStateChanged;116             if (target is Control)117             {118                 ((Control)target).Click -= OnClick;119             }120             if (target is ToolStripItem)121             {122                 ((Control)target).Click -= OnClick;123             }124         } 125     }
    CommandTarget 代碼
  5. 命令綁定管理器(CommandBindingManager)

    命令綁定管理器提供命令綁定(CommandBinding)與命令控件(WinForm控件)注冊與反注冊功能。

      1     /// <summary>  2     /// 表示命令注冊管理器。  3     /// </summary>  4     public static class CommandBindingManager  5     {  6         private static readonly List<CommandTarget> targets = new List<CommandTarget>();  7   8         /// <summary>  9         /// 注冊命令道指定的命令控件。 10         /// </summary> 11         /// <param name="control">綁定目標。</param> 12         /// <param name="commandBinding">命令綁定源。</param> 13         /// <returns>返回一個命令目標實例。</returns> 14         public static CommandTarget Register(Control control, CommandBinding commandBinding) 15         { 16             var target = new CommandTarget(control, commandBinding); 17             targets.Add(target); 18             return target; 19         } 20  21         /// <summary> 22         /// 注冊命令道指定的命令控件。 23         /// </summary> 24         /// <param name="stripItem">綁定目標。</param> 25         /// <param name="commandBinding">命令綁定源。</param> 26         /// <returns>返回一個命令目標實例。</returns> 27         public static CommandTarget Register(ToolStripItem stripItem, CommandBinding commandBinding) 28         { 29             var target = new CommandTarget(stripItem, commandBinding); 30             targets.Add(target); 31             return target; 32         } 33  34         /// <summary> 35         /// 注冊命令道指定的命令控件。 36         /// </summary> 37         /// <param name="control">綁定目標。</param> 38         /// <param name="command">綁定命令。</param> 39         /// <returns>返回一個命令目標實例。</returns> 40         public static CommandTarget Register(Control control, Command command) 41         { 42             return Register(control, new CommandBinding(command)); 43         } 44         /// <summary> 45         /// 注冊命令道指定的命令控件。 46         /// </summary> 47         /// <param name="stripItem">綁定目標。</param> 48         /// <param name="command">綁定命令。</param> 49         /// <returns>返回一個命令目標實例。</returns> 50         public static CommandTarget Register(ToolStripItem stripItem, Command command) 51         { 52             return Register(stripItem, new CommandBinding(command)); 53         } 54  55         /// <summary> 56         /// 注冊命令道指定的命令控件。 57         /// </summary> 58         /// <param name="control">綁定目標。</param> 59         /// <param name="command">綁定命令。</param> 60         /// <param name="source">構造命令參數的源。</param> 61         /// <param name="propertyName">構造命令參數的名稱。</param> 62         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param> 63         /// <returns>返回一個命令目標實例。</returns> 64         public static CommandTarget Register(Control control, Command command, object source, string propertyName, bool booleanOppose = false) 65         { 66             var commandBinding = new CommandBinding(command, source, propertyName, booleanOppose); 67             return Register(control, commandBinding); 68         } 69  70         /// <summary> 71         /// 注冊命令道指定的命令控件。 72         /// </summary> 73         /// <param name="stripItem">綁定目標。</param> 74         /// <param name="command">綁定命令。</param> 75         /// <param name="source">構造命令參數的源。</param> 76         /// <param name="propertyName">構造命令參數的名稱。</param> 77         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param> 78         /// <returns>返回一個命令目標實例。</returns> 79         public static CommandTarget Register(ToolStripItem stripItem, Command command, object source, string propertyName, bool booleanOppose = false) 80         { 81             var commandBinding = new CommandBinding(command, source, propertyName, booleanOppose); 82             return Register(stripItem, commandBinding); 83         } 84  85         /// <summary> 86         /// 注冊命令道指定的命令控件。 87         /// </summary> 88         /// <param name="control">綁定目標。</param> 89         /// <param name="command">綁定命令。</param> 90         /// <param name="staticSourceType">靜態類類型。</param> 91         /// <param name="propertyName">構造命令參數的名稱。</param> 92         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param> 93         /// <returns>返回一個命令目標實例。</returns> 94         public static CommandTarget Register(Control control, Command command, Type staticSourceType, string propertyName, bool booleanOppose = false) 95         { 96             var commandBinding = new CommandBinding(command, staticSourceType, propertyName, booleanOppose); 97             return Register(control, commandBinding); 98         } 99         /// <summary>100         /// 注冊命令道指定的命令控件。101         /// </summary>102         /// <param name="stripItem">綁定目標。</param>103         /// <param name="command">綁定命令。</param>104         /// <param name="staticSourceType">靜態類類型。</param>105         /// <param name="propertyName">構造命令參數的名稱。</param>106         /// <param name="booleanOppose">若值為System.Boolean值時,是否取反向值。</param>107         /// <returns>返回一個命令目標實例。</returns>108         public static CommandTarget Register(ToolStripItem stripItem, Command command, Type staticSourceType, string propertyName, bool booleanOppose = false)109         {110             var commandBinding = new CommandBinding(command, staticSourceType, propertyName, booleanOppose);111             return Register(stripItem, commandBinding);112         }113          114         /// <summary>115         /// 反注冊命令。116         /// </summary>117         /// <param name="target">注銷的命令目標。</param>118         public static void Unregister(CommandTarget target)119         {120             if (target == null)121             {122                 return;123             }124             if (targets.Contains(target))125             {126                 targets.Remove(target);127                 target.Dispose();128             }129         }130     }
    CommandBindingManager 代碼

     

最后附上委托命令(DegelateCommand)的實現。

 1     /// <summary> 2     /// 表示一個可被執行委托的方法的命令。 3     /// </summary> 4     public sealed class DelegateCommand : Command 5     { 6         private Action<object> execute; 7         private Func<object, bool> canExecute; 8         /// <summary> 9         /// 初始化 <see cref="DelegateCommand"/> 新實例。10         /// </summary>11         /// <param name="execute">當命令被調用時,指定的方法。</param>12         /// <param name="canExecute">當命令被確定是否能執行時,執行的方法。</param>13         public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)14         {15             this.execute = execute;16             this.canExecute = canExecute;17         }18         /// <summary>19         /// 定義用于確定此命令是否可以在其當前狀態下執行的方法。20         /// </summary>21         /// <param name="parameter">此命令使用的數據。 如果此命令不需要傳遞數據,則該對象可以設置為 null。</param>22         /// <returns>如果可以執行此命令,則為 true;否則為 false。</returns>23         public override bool CanExecute(object parameter)24         {25             if (canExecute == null)26             {27                 return true;28             }29             return canExecute(parameter);30         }31 32         /// <summary>33         /// 定義在調用此命令時調用的方法。34         /// </summary>35         /// <param name="parameter">此命令使用的數據。 如果此命令不需要傳遞數據,則該對象可以設置為 null。</param>36         public override void Execute(object parameter)37         {38             if (CanExecute(parameter))39             {40                 execute(parameter);41             }42         }43     } 
DelegateCommand 代碼

 

   補充:不好意思,忘記附上Demo示例,現補上,請前往 百度網盤 下載

 

  本文如有紕漏,歡迎大家批評指正!                                   


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 综合激情网| 日韩av电影在线免费观看 | 精品视频 久久久 | 日本成人午夜 | 性欧美大战久久久久久久免费观看 | 久久免费视频精品 | 91九色精品国产 | 日韩视频中文 | xxxx hd videos| 国产一区二区免费在线观看 | 日韩视频1 | 秋霞a级毛片在线看 | 久久性生活免费视频 | 久草干| 91精品国产综合久久久动漫日韩 | 国产一区免费在线 | 色人阁五月天 | 日本成人一二三区 | 国产精品久久久久久久娇妻 | 国产精品刺激对白麻豆99 | 国产成人综合在线观看 | 黄色高清视频网站 | 日本人乱人乱亲乱色视频观看 | 色七七亚洲 | 男人的天堂视频网站 | 香蕉久久久久久 | av电影院在线观看 | 伊人久操视频 | 欧美 日韩 国产 成人 | 斗罗破苍穹在线观看免费完整观看 | 午夜久| 午夜激情视频免费 | 欧美一区二区片 | 久久毛片| 香蕉视频99 | 黄色av网站免费 | 国产精品久久久久久久久久尿 | 久久久久免费精品国产小说色大师 | 一区二区国产在线 | 一区二区三区日韩在线 | www.91在线 |