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支援更多,
以後不只開發更容易分工,軟體直接改皮就可以當作下一版,老闆也會說你好棒呢!!