在WPF自學入門(十)WPF MVVM簡單介紹中的示例似乎運作起來沒有什麼問題,也可以進行更新。但是這并不是我們使用MVVM的正确方式。正如上一篇文章中在開始說的,MVVM的目的是為了最大限度地降低了Xaml檔案和CS檔案的耦合度,分離界面和業務邏輯,是以我們要盡可能的在View背景不寫代碼。但是這個例子中,我們将更新ViewModel的代碼寫在了View裡,下一個例子中,我們要通過指令(Command)的來将Button的事件分離出來。
因為本文中需要使用Command指令,我們先來簡單了解Command指令。在WPF中使用指令的步驟很簡單
1.建立指令
2.綁定指令
3.設定指令源
4.設定指令目标
WPF中指令的核心是System.Windows.Input.ICommand接口,所有指令對象都實作了此接口。當建立自己的指令時,不能直接實作ICommand接口,而是要使用System.Windows.Input.RouteCommand類,該類已經實作了ICommand接口,所有WPF指令都是RouteCommand類的執行個體。在程式中處理的大部分指令不是RoutedCommand對象,而是RoutedUICommand類的執行個體,它繼承自RouteCommand類。
WPF提供了一個很好的方式來解決事件綁定的問題--ICommand。很多控件都有Command屬性,如果沒有,我們可以将指令綁定到觸發器上。接下來我們來先實作一個ICommand接口。ICommand需要使用者定義兩個方法bool CanExecute和void Execute。第一個方法可以讓我們來判斷是否可以執行這個指令,第二個方法就是我們具體的指令。
1 using System;
2
3 using System.Collections.Generic;
4
5 using System.Linq;
6
7 using System.Text;
8
9 using System.Windows.Input;
10
11
12
13 /***********************作者:黃昏前黎明後**********************************
14
15 * 作者:黃昏前黎明後
16
17 * CLR版本:4.0.30319.42000
18
19 * 建立時間:2018-04-05 22:57:56
20
21 * 命名空間:Example3
22
23 * 唯一辨別:b9043d4c-fdd7-4e0f-a324-00f0f09286d0
24
25 * 機器名稱:HLPC
26
27 * 聯系人郵箱:[email protected]
28
29 *
30
31 * 描述說明:
32
33 *
34
35 * 修改曆史:
36
37 *
38
39 *
40
41 *****************************************************************/
42
43 namespace Example3
44
45 {
46
47 public class RelayCommand : ICommand
48
49 {
50
51 #region 字段
52
53 readonly Func<Boolean> _canExecute;
54
55 readonly Action _execute;
56
57 #endregion
58
59
60
61 #region 構造函數
62
63 public RelayCommand(Action execute)
64
65 : this(execute, null)
66
67 {
68
69 }
70
71 public RelayCommand(Action execute, Func<Boolean> canExecute)
72
73 {
74
75 if (execute == null)
76
77 throw new ArgumentNullException("execute");
78
79 _execute = execute;
80
81 _canExecute = canExecute;
82
83 }
84
85 #endregion
86
87
88
89 #region ICommand的成員
90
91 public event EventHandler CanExecuteChanged
92
93 {
94
95 add
96
97 {
98
99
100
101 if (_canExecute != null)
102
103 CommandManager.RequerySuggested += value;
104
105 }
106
107 remove
108
109 {
110
111
112
113 if (_canExecute != null)
114
115 CommandManager.RequerySuggested -= value;
116
117 }
118
119 }
120
121
122
123 [DebuggerStepThrough]
124
125 public Boolean CanExecute(Object parameter)
126
127 {
128
129 return _canExecute == null ? true : _canExecute();
130
131 }
132
133
134
135 public void Execute(Object parameter)
136
137 {
138
139 _execute();
140
141 }
142
143 #endregion
144
145 }
146
147 }
148
149
我們再在我們的NameViewModel中聲明一個ICommand字段:
1 #region 指令
2
3 void UpdateNameExecute()
4
5 {
6
7 this.UserName = "黃昏前黎明後";
8
9 this.CompanyName = "中軟易通科技";
10
11 }
12
13
14
15 bool CanUpdateNameExecute()
16
17 {
18
19 return true;
20
21 }
22
23
24
25 public ICommand UpdateName { get { return new RelayCommand(UpdateNameExecute, CanUpdateNameExecute); } }
26
27
28
29 #endregion
最後,我們再将事件綁定上這個Command:
<Button Content="更新" Command="{Binding UpdateName}" Margin="20"/>
運作一下,看結果。我們成功将事件分離了出來。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CM0YTO1QDMxETMtIjMygzM0MzMyUDM0ADOxAjMtIDNzIjN28CX0ADOxAjMvwlM0MjM2YzLcd2bsJ2Lc12bj5ycn9Gbi52YugTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
看到上面的結果,似乎目前為止我們已經很好的解決了所有的問題。我們看到運作的資料,事件都是綁定的,實作了界面的完美分離。實際在處理問題是好像需要考慮通用性,這時我們能否把MVVM提取出來作為一個架構,來去更好的解決問題。下一次我們一起來看看怎麼進行提取成為通用架構。
本文的DEMO下載下傳位址:WPFMVVMDemo2.zip
https://pan.baidu.com/s/1xZvsrMbDOXlpvDbCh2Af3Q 密碼:6666
小黎子,一個專注于資料分析整體資料倉庫解決方案的程式猿!
作 者:黃昏前黎明後
出 處:http://www.cnblogs.com/fly-bird/
歡迎關注個人公衆号:小黎子資料分析,轉載文章請務必注明出處。