转自
http://www.dotblogs.com.tw/help/archive/2010/07/29/16888.aspx
使用MVVM开发方式,可以让程式逻辑与介面分离,
介面设计者只需要知道资料的名称就可以开发介面,
也因此动态更换介面也变得非常容易。
这边我们先设计一个简单的Model和ViewModel
Model就让他有三个栏位,姓名、电话与信箱
ViewModel就做了一个List和时分秒的栏位,以及启动与停止计时的函式,内容如下:
1: public class DemoViewModel : INotifyPropertyChanged{
2: private System.Windows.Threading.DispatcherTimer Timer;
3:
4: private string _Title;
5: private int _Hour;
6: private int _Minute;
7: private int _Second;
8: private ObservableCollection<UserCard> _UserCardList;
9: private ICommand _StartTimerCommand;
10: private ICommand _EndTimerCommand;
11:
12: public string Title {
13: get { return _Title; }
14: set {
15: _Title = value ;
16: Update( "Title" );
17: }
18: }
19:
20:
21: public int Hour {
22: get { return _Hour; }
23: set {
24: _Hour = value ;
25: Update( "Hour" );
26: }
27: }
28:
29:
30: public int Minute {
31: get { return _Minute; }
32: set {
33: _Minute = value ;
34: Update( "Minute" );
35: }
36: }
37:
38:
39: public int Second {
40: get { return _Second; }
41: set {
42: _Second = value ;
43: Update( "Second" );
44: }
45: }
46:
47:
48: public ObservableCollection<UserCard> UserCardList {
49: get { return _UserCardList; }
50: set {
51: _UserCardList = value ;
52: Update( "UserCardList" );
53: }
54: }
55:
56: public ICommand StartTimerCommand {
57: get {
58: if (_StartTimerCommand == null ) _StartTimerCommand = new ActionCommand(StartTimer);
59: return _StartTimerCommand;
60: }
61: }
62:
63:
64: public ICommand EndTimerCommand {
65: get {
66: if (_EndTimerCommand == null ) _EndTimerCommand = new ActionCommand(EndTimer);
67: return _EndTimerCommand;
68: }
69: }
70:
71:
72: public DemoViewModel() {
73: _Title = "Dynamic Demo" ;
74: _UserCardList = new ObservableCollection<UserCard>();
75: _UserCardList.Add( new UserCard( "A" , "1234567" , "[email protected]" ));
76: _UserCardList.Add( new UserCard( "B" , "7654321" , "[email protected]" ));
77: _UserCardList.Add( new UserCard( "C" , "1357246" , "[email protected]" ));
78: _UserCardList.Add( new UserCard( "D" , "2461357" , "[email protected]" ));
79: _UserCardList.Add( new UserCard( "E" , "28825252" , "[email protected]" ));
80: _UserCardList.Add( new UserCard( "F" , "55178" , "[email protected]" ));
81: _UserCardList.Add( new UserCard( "G" , "3345678" , "[email protected]" ));
82: }
83:
84: private void Timer_Tick( object sender, EventArgs e) {
85: Hour = DateTime.Now.Hour;
86: Minute = DateTime.Now.Minute;
87: Second = DateTime.Now.Second;
88: }
89:
90: private void StartTimer() {
91: Timer = new System.Windows.Threading.DispatcherTimer();
92: Timer.Interval = TimeSpan.FromSeconds(1);
93: Timer.Tick += new EventHandler(Timer_Tick);
94: Timer.Start();
95: }
96:
97: private void EndTimer() {
98: Timer.Stop();
99: }
100:
101: private void Update( string name) {
102: if (PropertyChanged != null ) PropertyChanged( this , new PropertyChangedEventArgs(name));
103: }
104:
105: #region INotifyPropertyChanged Members
106:
107: public event PropertyChangedEventHandler PropertyChanged;
108:
109: #endregion
110: }
然后做出一个基本款的介面,
基本介面被一个Border包起来,所以黑框内的才是预设的基本介面,之后我们另外制作一个xaml档,档名为DemoSkin001.xaml,内容如下:
1: < UserControl
2: xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
5: xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
6: xmlns:sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
7: xmlns:i ="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei ="http://schemas.microsoft.com/expression/2010/interactions"
8: mc:Ignorable ="d"
9: d:DesignWidth ="640" d:DesignHeight ="480" >
10:
11: < Grid x:Name ="LayoutRoot" >
12: < sdk:DataGrid x:Name ="dataGrid" AreRowGroupHeadersFrozen ="False" HorizontalAlignment ="Left" Width ="205" ScrollViewer . HorizontalScrollBarVisibility ="Auto" ScrollViewer . VerticalScrollBarVisibility ="Auto" ItemsSource ="{Binding UserCardList}" Margin ="137,8,0,0" Height ="215" VerticalAlignment ="Top" >
13: < sdk:DataGrid.Columns >
14: < sdk:DataGridTextColumn Binding ="{Binding Name}" Header ="Name" />
15: < sdk:DataGridTextColumn Binding ="{Binding Phone}" Header ="Phone" />
16: < sdk:DataGridTextColumn Binding ="{Binding Email}" Header ="Email" />
17: </ sdk:DataGrid.Columns >
18: </ sdk:DataGrid >
19: < ComboBox Margin ="8,28,0,0" VerticalAlignment ="Top" ItemsSource ="{Binding UserCardList}" DisplayMemberPath ="Name" SelectedItem ="{Binding SelectedItem, ElementName=dataGrid, Mode=TwoWay}" HorizontalAlignment ="Left" Width ="125" d:LayoutOverrides ="HorizontalAlignment" />
20: < StackPanel Margin ="8,8,0,0" Orientation ="Horizontal" Height ="16" VerticalAlignment ="Top" d:LayoutOverrides ="Height" HorizontalAlignment ="Left" Width ="125" >
21: < TextBlock HorizontalAlignment ="Left" TextWrapping ="Wrap" Text ="现在时间:" />
22: < TextBlock HorizontalAlignment ="Left" TextWrapping ="Wrap" Text ="{Binding Hour}" Height ="16" Margin ="5,0,0,0" />
23: < TextBlock TextWrapping ="Wrap" Text ="{Binding Minute, StringFormat=':{0}'}" Height ="16" HorizontalAlignment ="Left" />
24: < TextBlock TextWrapping ="Wrap" Text ="{Binding Second, StringFormat=':{0}'}" Height ="16" HorizontalAlignment ="Left" />
25: </ StackPanel >
26: </ Grid >
27: </ UserControl >
此xaml不能有相对应的cs档,所以也不能有x:Class属性。
然后按Open按钮开启这个xaml档
介面就直接改变了!
是不是很方便啊!(我是觉得很方便啦!)
MVVM开发方式不是只能用在Silverlight喔~WPF支援更多,
以后不只开发更容易分工,软体直接改皮就可以当作下一版,老板也会说你好棒呢!!