MVVM
(Model-View-ViewModel)模式是MVC模式在Silverlight/WPF中的一個升華,利用強大的數據綁定可以做到更加方便易用。原則和MVC一樣:UI和Model綁定,Controller操作Model,Controller代碼不寫在UI層中,Controller不直接操作UI層。分層隔離,方便單元測試
MVVM的終極目的:不要在xaml.cs中寫代碼。消滅OnClick!
Button的Command屬性是ICommand類型的,當點擊按鈕的時候ICommand的Execute方法就會被執行。Execute方法的parameter參數值就是CommandParameter屬性的值
例子:我們做一個驗證登陸的小程序;在界面上放置兩個文本框和一個登陸按鈕,畫好界面后我們新建一個類Login
1 public class Login:DependencyObject 2 { 3 4 5 public string userName 6 { 7 get { return (string)GetValue(userNameProperty); } 8 set { SetValue(userNameProperty, value); } 9 } 10 11 // Using a DependencyProperty as the backing store for userName. This enables animation, styling, binding, etc... 12 public static readonly DependencyProperty userNameProperty = 13 DependencyProperty.Register("userName", typeof(string), typeof(Login),null 14 ); 15 16 17 18 public string pwd 19 { 20 get { return (string)GetValue(pwdProperty); } 21 set { SetValue(pwdProperty, value); } 22 } 23 24 // Using a DependencyProperty as the backing store for pwd. This enables animation, styling, binding, etc... 25 public static readonly DependencyProperty pwdProperty = 26 DependencyProperty.Register("pwd", typeof(string), typeof(Login), null); 27 28 29 public ICommand denglu 30 { 31 get { return new LoginCommand(); } 32 } 33 public delegate void LoginDelegate(bool b);//定義一個委托 34 public event LoginDelegate LoginIsSucces;//注冊一個事件 35 //事件就是一個私有的委托加上兩個方法(add,remove) 36 public void FireLoginComplete(bool b) 37 { 38 if (LoginIsSucces!=null) 39 { 40 LoginIsSucces(b); 41 } 42 } 43 } 44 public class LoginCommand : ICommand 45 { 46 // CanExecute 決定Execute是否可用 47 public bool CanExecute(object parameter) 48 { 49 return true; 50 } 51 //這里可以修改CanExecute的值 52 public event EventHandler CanExecuteChanged; 53 54 public void Execute(object parameter) 55 { 56 Login login = (Login)parameter; 57 if (login.userName=="admin"&&login.pwd=="123") 58 { 59 login.FireLoginComplete(true); 60 } 61 else 62 { 63 login.FireLoginComplete(false); 64 } 65 } 66 }
mvvm模式在小的應用上寫起來不怎么方便,但是在項目大的情況下就優勢很明顯了!非常的靈活
給登陸按鈕注冊事件:
1 private void button1_Click(object sender, RoutedEventArgs e) 2 { 3 Login login=(Login)this.Resources["login"]; 4 login.LoginIsSucces += new Login.LoginDelegate(login_LoginIsSucces); 5 } 6 7 void login_LoginIsSucces(bool b) 8 { 9 if (b) 10 { 11 MessageBox.Show("登錄成功"); 12 } 13 else { 14 MessageBox.Show("登錄失敗"); 15 } 16 17 }
這樣我們就可以根據返回值在表現層任意的修改表現的形式!
擴展一個小知識:
給控件注冊事件:
第一:添加引用:System.Windows.Interactivity
第二:導入命名空間
1 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
第三;
1 <TextBlock Height="30" HorizontalAlignment="Left" Margin="132,390,0,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" > 2 <i:Interaction.Triggers> 3 <i:EventTrigger EventName="Tap"> 4 <i:InvokeCommandAction Command="{Binding denglu}" CommandParameter="{Binding}"> 5 6 </i:InvokeCommandAction> 7 </i:EventTrigger> 8 </i:Interaction.Triggers> 9 </TextBlock>
獨立存儲
比如我們想實現這個一個方法,一個登陸界面,當我們成功登陸后,自動記錄用戶名密碼;並且在下次登陸的時候自動給登陸文本框賦值
后台代碼:
1 private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) 2 { 3 if (IsolatedStorageSettings.ApplicationSettings.Contains("username")) 4 { 5 userName.Text = (string)IsolatedStorageSettings.ApplicationSettings["username"]; 6 } 7 if (IsolatedStorageSettings.ApplicationSettings.Contains("pwd")) 8 { 9 pwd.Text = (string)IsolatedStorageSettings.ApplicationSettings["pwd"]; 10 } 11 12 } 13 14 private void button1_Click(object sender, RoutedEventArgs e) 15 { 16 IsolatedStorageSettings.ApplicationSettings["username"] = userName.Text; 17 IsolatedStorageSettings.ApplicationSettings["pwd"] = pwd.Text; 18 IsolatedStorageSettings.ApplicationSettings.Save(); 19 MessageBox.Show("登錄成功,已經記錄你當前的登錄信息"); 20 }
系統是怎么保存我們存在里面的鍵值對呢?其實是在系統里面生成了一個類似於txt文檔的東西,來幫我們存儲,並且文件的名稱含有ApplicationSettings字符,從手機里面可以看出來,所以我們以后如果要創建文件,最好不要創建含有ApplicationSettings字符的文件,以免把系統的文件覆蓋!
當然我們也可以創建我們專屬的文件,但是創建的文件僅限我們的自己的程序集,無法訪問,或創建其它跨程序集的文件,微軟在考慮安全的同時對此做了限制:
1 private void button1_Click(object sender, RoutedEventArgs e) 2 { 3 IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication(); 4 using (IsolatedStorageFileStream stream = isf.CreateFile("config.txt")) 5 { 6 using (StreamWriter writer = new StreamWriter(stream)) 7 { 8 writer.WriteLine(textBox1.Text + "|" + textBox2.Text); 9 } 10 } 11 } 12 13 private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) 14 { 15 IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication(); 16 if (isf.FileExists("config.txt")) 17 { 18 using (IsolatedStorageFileStream stream = isf.OpenFile("config.txt", FileMode.Open)) 19 { 20 using (StreamReader reader = new StreamReader(stream)) 21 { 22 string[] line=reader.ReadLine().Split('|'); 23 textBox1.Text = line[0]; 24 textBox2.Text = line[1]; 25 } 26 } 27 } 28 }