天天看點

WPF自學入門(十二)WPF MVVM模式提取函數

      我們平時在寫代碼時為了不重複寫代碼,會進行複制代碼或者寫通用方法。今天我們就來把上傳做的函數提取成為通用的方法調用。把上次寫的函數提取為兩個主要的檔案:ObserableObject和RelayCommand。步驟如下:

   建立Mvvm項目,将執行個體三中的檔案複制到Mvvm項目中即可。建立ObserableObject類檔案,代碼如下:

1 using System;
  2 
  3 using System.ComponentModel;
  4 
  5 using System.Diagnostics;
  6 
  7 using System.Linq.Expressions;
  8 
  9 /***********************作者:黃昏前黎明後**********************************
 10 
 11 *   作者:黃昏前黎明後
 12 
 13 *   CLR版本:4.0.30319.42000
 14 
 15 *   建立時間:2018-04-15 22:09:56
 16 
 17 *   命名空間:Mvvm
 18 
 19 *   唯一辨別:b9043d4c-fdd7-4e0f-a324-00f0f09286d0
 20 
 21 *   機器名稱:HLPC
 22 
 23 *   聯系人郵箱:[email protected]
 24 
 25 *
 26 
 27 *   描述說明:
 28 
 29 *
 30 
 31 *   修改曆史:
 32 
 33 *
 34 
 35 *
 36 
 37 *****************************************************************/
 38 
 39 namespace Mvvm
 40 
 41 {
 42 
 43     [Serializable]
 44 
 45     public abstract class ObservableObject : INotifyPropertyChanged
 46 
 47     {
 48 
 49         [field: NonSerialized]
 50 
 51         public event PropertyChangedEventHandler PropertyChanged;
 52 
 53  
 54 
 55         protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
 56 
 57         {
 58 
 59             var handler = this.PropertyChanged;
 60 
 61             if (handler != null)
 62 
 63             {
 64 
 65                 handler(this, e);
 66 
 67             }
 68 
 69         }
 70 
 71  
 72 
 73         protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
 74 
 75         {
 76 
 77             var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion);
 78 
 79             this.RaisePropertyChanged(propertyName);
 80 
 81         }
 82 
 83  
 84 
 85         protected void RaisePropertyChanged(String propertyName)
 86 
 87         {
 88 
 89             VerifyPropertyName(propertyName);
 90 
 91             OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
 92 
 93         }
 94 
 95  
 96 
 97         [Conditional("DEBUG")]
 98 
 99         [DebuggerStepThrough]
100 
101         public void VerifyPropertyName(String propertyName)
102 
103         {
104 
105             if (TypeDescriptor.GetProperties(this)[propertyName] == null)
106 
107             {
108 
109                 Debug.Fail("無效屬性名: " + propertyName);
110 
111             }
112 
113         }
114 
115     }
116 
117 }      

        前面我們都是使用單個的使用者名,接下來我們嘗試使用多個使用者名。按照我們一開始所說的,我們需要一個ObservableCollection的集合。是以我們需要新增一個ViewModel名稱NamesViewModel:

1 using Mvvm;
  2 
  3 using System;
  4 
  5 using System.Collections.Generic;
  6 
  7 using System.Collections.ObjectModel;
  8 
  9 using System.Linq;
 10 
 11 using System.Text;
 12 
 13 using System.Windows.Input;
 14 
 15  
 16 
 17 /****************************************************************
 18 
 19 *   作者:黃昏前黎明後
 20 
 21 *   CLR版本:4.0.30319.42000
 22 
 23 *   建立時間:2018-04-15 22:32:29
 24 
 25 *   命名空間:Example4.ViewModel
 26 
 27 *   唯一辨別:d500d890-7083-4f05-a82a-45f27eaa26d9
 28 
 29 *   機器名稱:HLPC
 30 
 31 *   聯系人郵箱:[email protected]
 32 
 33 *
 34 
 35 *   描述說明:
 36 
 37 *
 38 
 39 *   修改曆史:
 40 
 41 *
 42 
 43 *
 44 
 45 *****************************************************************/
 46 
 47 namespace Example4
 48 
 49 {
 50 
 51     public class NamesViewModel
 52 
 53     {
 54 
 55         #region 字段
 56 
 57         ObservableCollection<NameViewModel> _names = new ObservableCollection<NameViewModel>();
 58 
 59         #endregion
 60 
 61  
 62 
 63         #region 屬性
 64 
 65         public ObservableCollection<NameViewModel> names
 66 
 67         {
 68 
 69             get { return _names; }
 70 
 71             set { _names = value; }
 72 
 73         }
 74 
 75         #endregion
 76 
 77  
 78 
 79         public NamesViewModel()
 80 
 81         {
 82 
 83             _names.Add(new NameViewModel() { UserName = "hl", CompanyName = "中軟易通" });
 84 
 85             _names.Add(new NameViewModel() { UserName = "lq", CompanyName = "中軟" });
 86 
 87             _names.Add(new NameViewModel() { UserName = "tp", CompanyName = "軟易通" });
 88 
 89         }
 90 
 91  
 92 
 93         #region 指令
 94 
 95  
 96 
 97         void AddNameExecute()
 98 
 99         {
100 
101             _names.Add(new NameViewModel { UserName = "黃昏前黎明後", CompanyName = "中軟易通科技" });
102 
103         }
104 
105  
106 
107         bool CanAddNameExecute()
108 
109         {
110 
111             return true;
112 
113         }
114 
115  
116 
117         void UpdateNameExecute(NameViewModel name)
118 
119         {
120 
121             if (name == null) return;
122 
123  
124 
125             name.CompanyName= "無";
126 
127         }
128 
129  
130 
131         bool CanUpdateNameExecute(NameViewModel name)
132 
133         {
134 
135             return true;
136 
137         }
138 
139  
140 
141         public ICommand AddName { get { return new RelayCommand(AddNameExecute, CanAddNameExecute); } }
142 
143  
144 
145         public ICommand UpdateName { get { return new RelayCommand<NameViewModel>(new Action<NameViewModel>(UpdateNameExecute), new Predicate<NameViewModel>(CanUpdateNameExecute)); } }
146 
147  
148 
149         #endregion
150 
151     }
152 
153 }
154 
155        

我們實作了兩個指令,一個是新增使用者,一個是把所有集合裡的公司名更改為無。然後我們把這個ViewModel綁定到界面上:

1 <Window x:Class="Example4.MainWindow"
 2 
 3         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 4 
 5         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 6 
 7         xmlns:local="clr-namespace:Example4"
 8 
 9         Title="Example4" Height="147.806" Width="407.044" ResizeMode="NoResize">
10 
11     <Window.DataContext>
12 
13         <!--聲明建立一個NamesViewModel的執行個體-->
14 
15         <local:NamesViewModel></local:NamesViewModel>
16 
17     </Window.DataContext>
18 
19  
20 
21     <StackPanel Orientation="Horizontal">
22 
23         <ListView ItemsSource="{Binding names}" Width="200" Name="lv">
24 
25             <ListView.ItemTemplate>
26 
27                 <DataTemplate>
28 
29                     <StackPanel Orientation="Horizontal">
30 
31                         <Label Content="{Binding UserName}" />
32 
33                         <Label Content="{Binding CompanyName}" FontSize="10" />
34 
35                     </StackPanel>
36 
37                 </DataTemplate>
38 
39             </ListView.ItemTemplate>
40 
41         </ListView>
42 
43         <StackPanel>
44 
45             <Button Content="新增使用者" Height="40" Margin="20" Command="{Binding AddName}"/>
46 
47             <Button Content="更新選中使用者" Height="40" Margin="20" Command="{Binding UpdateName}" CommandParameter="{Binding ElementName=lv,Path=SelectedItem}"/>
48 
49         </StackPanel>
50 
51  
52 
53     </StackPanel>
54 
55 </Window>
56 
57        

本文程式demo下載下傳位址:連結:https://pan.baidu.com/s/12EEoVVVRbI5EiRNusSz1zg 密碼:hbwb

結束語:WPF自學入門系列中對WPF的一些基本概念做了一些示範,但是還是有一些缺失,隻是希望能對初學者起到一定的幫助。

最後,感謝你能看到最後。從下周開始學習Component One控件使用。

小黎子,一個專注于資料分析整體資料倉庫解決方案的程式猿!

作 者:黃昏前黎明後

出 處:http://www.cnblogs.com/fly-bird/

歡迎關注個人公衆号:小黎子資料分析,轉載文章請務必注明出處。