Silverlight 4 MVVM開發方式(三) 動態換皮

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: }

然後做出一個基本款的介面,

001

基本介面被一個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檔

002

介面就直接改變了!

003

是不是很方便啊!(我是覺得很方便啦!)

MVVM開發方式不是只能用在Silverlight喔~WPF支援更多,

以後不只開發更容易分工,軟體直接改皮就可以當作下一版,老闆也會說你好棒呢!!

DynamicSkin.rar