Silverlight 4 MVVM開發方式(三) 動態換皮
使用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", "a@demo.com"));
76: _UserCardList.Add(new UserCard("B", "7654321", "b@demo.com"));
77: _UserCardList.Add(new UserCard("C", "1357246", "c@demo.com"));
78: _UserCardList.Add(new UserCard("D", "2461357", "d@demo.com"));
79: _UserCardList.Add(new UserCard("E", "28825252", "e@demo.com"));
80: _UserCardList.Add(new UserCard("F", "55178", "f@demo.com"));
81: _UserCardList.Add(new UserCard("G", "3345678", "g@demo.com"));
  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支援更多,
以後不只開發更容易分工,軟體直接改皮就可以當作下一版,老闆也會說你好棒呢!!



