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 }