AngularJS利刃 MVVMLight 3:双向数据绑定

     
上篇大家已老董解了MVVM的框架结构和运行原理。这里我们来看一下宏伟的双向数据绑定。

说到双向绑定,大家相比较熟练的相应就是AngularJS了,几乎所有的AngularJS
序列教程的开业几章都要涉及到,真的是很好用。

宣布的职能很简短:就是在界面的操作对数据模型的改动能实时反映到多少;而数据的改观能实时显示到界面。即视图数据模型(ViewModel)和视图(View)之间的双向绑定和接触。

 

AngularJS 1

 

 

俺们来操作一个试跳看:

首先步:先写一个Model,里面含有大家需要的数码音讯,代码如下:

 1     /// <summary>
 2     /// 用户信息
 3     /// </summary>
 4     public class UserInfoModel : ObservableObject
 5     {
 6         private String userName;
 7         /// <summary>
 8         /// 用户名称
 9         /// </summary>
10         public String UserName
11         {
12             get { return userName; }
13             set { userName = value; RaisePropertyChanged(()=>UserName); }
14         }
15 
16         private Int64 userPhone;
17         /// <summary>
18         /// 用户电话
19         /// </summary>
20         public Int64 UserPhone
21         {
22             get { return userPhone; }
23             set { userPhone = value; RaisePropertyChanged(() => UserPhone); }
24         }
25 
26         private Int32 userSex;
27         /// <summary>
28         /// 用户性别
29         /// </summary>
30         public Int32 UserSex
31         {
32             get { return userSex; }
33             set { userSex = value; RaisePropertyChanged(()=>UserSex); }
34         }
35 
36         private String userAdd;
37         /// <summary>
38         /// 用户地址
39         /// </summary>
40         public String UserAdd
41         {
42             get { return userAdd; }
43             set { userAdd = value; RaisePropertyChanged(() => UserAdd); }
44         }
45     }

 

第二步:写一个ViewModel,包含了View所需要的一声令下和属性:

 1     public class BothWayBindViewModel:ViewModelBase
 2     {
 3         public BothWayBindViewModel()
 4         {
 5             UserInfo = new UserInfoModel();
 6         }
 7         
 8         #region 属性
 9 
10         private UserInfoModel userInfo;
11         /// <summary>
12         /// 用户信息
13         /// </summary>
14         public UserInfoModel UserInfo
15         {
16             get { return userInfo; }
17             set { userInfo = value; RaisePropertyChanged(() => UserInfo); }
18         }
19 
20         #endregion
21         
22         #region 命令
23         #endregion
24     }

 

其三步:在ViewModelLocator中注册我们写好的ViewModel:SimpleIoc.Default.Register<BothWayBindViewModel>();

 1 /*
 2   In App.xaml:
 3   <Application.Resources>
 4       <vm:ViewModelLocator xmlns:vm="clr-namespace:MVVMLightDemo"
 5                            x:Key="Locator" />
 6   </Application.Resources>
 7   
 8   In the View:
 9   DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
10 
11   You can also use Blend to do all this with the tool's support.
12   See http://www.galasoft.ch/mvvm
13 */
14 
15 using GalaSoft.MvvmLight;
16 using GalaSoft.MvvmLight.Ioc;
17 using Microsoft.Practices.ServiceLocation;
18 
19 namespace MVVMLightDemo.ViewModel
20 {
21     /// <summary>
22     /// This class contains static references to all the view models in the
23     /// application and provides an entry point for the bindings.
24     /// </summary>
25     public class ViewModelLocator
26     {
27         /// <summary>
28         /// Initializes a new instance of the ViewModelLocator class.
29         /// </summary>
30         public ViewModelLocator()
31         {
32             ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
33 
34             #region Code Example
35             ////if (ViewModelBase.IsInDesignModeStatic)
36             ////{
37             ////    // Create design time view services and models
38             ////    SimpleIoc.Default.Register<IDataService, DesignDataService>();
39             ////}
40             ////else
41             ////{
42             ////    // Create run time view services and models
43             ////    SimpleIoc.Default.Register<IDataService, DataService>();
44             ////}
45             #endregion
46 
47             SimpleIoc.Default.Register<MainViewModel>();
48             SimpleIoc.Default.Register<WelcomeViewModel>();
49             SimpleIoc.Default.Register<BothWayBindViewModel>();    
50         }
51 
52         #region 实例化
53         public MainViewModel Main
54         {
55             get
56             {
57                 return ServiceLocator.Current.GetInstance<MainViewModel>();
58             }
59         }
60 
61         public WelcomeViewModel Welcome
62         {
63             get
64             { 
65                return ServiceLocator.Current.GetInstance<WelcomeViewModel>();
66             }
67         }
68 
69         public BothWayBindViewModel BothWayBind
70         {
71             get
72             { 
73                 return ServiceLocator.Current.GetInstance<BothWayBindViewModel>();
74             }
75         }     
76 
77         #endregion
78 
79         public static void Cleanup()
80         {
81             // TODO Clear the ViewModels
82         }
83     }
84 }

 

第四步:编写View(注意标红的代码):

 

 1 <Window x:Class="MVVMLightDemo.View.BothWayBindView"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         DataContext="{Binding Source={StaticResource Locator},Path=BothWayBind}"
 5         Title="BothWayBindView" Height="300" Width="300">
 6     <Grid>
 7             <StackPanel Orientation="Vertical" Margin="10,10,0,0">
 8                 <StackPanel Orientation="Horizontal" >
 9                     <TextBlock Text="请输入姓名:" ></TextBlock>
10                     <TextBox Text="{Binding UserInfo.UserName,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Width="200" ></TextBox>
11                 </StackPanel>
12 
13                 <StackPanel Margin="0,10,0,0" Orientation="Horizontal" >
14                     <TextBlock Text="Hello " ></TextBlock>
15                     <TextBlock Text="{Binding UserInfo.UserName}" ></TextBlock>
16                 </StackPanel>
17 
18                 <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" >
19                 </StackPanel>
20                 
21             </StackPanel>
22     </Grid>
23 </Window>

效用如图所示(当修改输入框的始末的时候,对应绑定数据对应变更,并触及对UI的改动,所以下边这行文字也呼应改变改变。):

AngularJS 2

 

面前大家已经精通到了,RaisePropertyChanged的效能是当数据源改变的时候,会触发PropertyChanged事件达到通告UI更改的目标(ViewModel => View)。

 

这View上的转变要怎么通知到数据源呢:

View中文本框绑定内容如下:{Binding
UserInfo.UserName,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay},

世家会晤到多了六个特性,一个是UpdateSourceTrigger,一个是Mode属性。

UpdateSourceTrigger的意义是 当做何种改变的时候通告数据源我们做了转移。

 

 

枚举类型 效果
Default 默认值(默认为LostFocuse)
Explicit 当应用程序调用 UpdateSource 方法时生效
LostFocus 失去焦点的时候触发
PropertyChanged 数据属性改变的时候触发

 

这边我们一贯利用
PropertyChanged,当UI数据变动的时候,大家再通知到数据源去做修改。

 

 

还有一个特性就是Mode,他有五个参数:

枚举类型 效果
OneWay 源发生变化,数据就会从源流向目标
OneTime 绑定会将数据从源发送到目标;但是,仅当启动了应用程序或 DataContext 发生更改时才会如此操作,因此,它不会侦听源中的更改通知。
OneWayToSource 绑定会将数据从目标发送到源
TwoWay 绑定会将源数据发送到目标,但如果目标属性的值发生变化,则会将它们发回给源
Default 绑定的模式根据实际情况来定,如果是可编辑的就是TwoWay,只读的就是OneWay

 

 

这边显著有很多种精选,明确一点的是,我们是想把View上的转移同步到ViewModel(Target =>
Source),所以采用OneWayToSource、TwoWay、Default或者不写都可以。

严峻点应该拔取OneWayToSource。因为是文本框,属于可以编写控件,所以
Default指向的是TwoWay。

下边还有一个TextBlock,仅仅用于体现的,所以不需要目的对源的改动,无需指定就默认是OneWay,当源改变的时候,会通报它举行修改。

 

点击下载代码

 

转载请标明出处,谢谢

 

相关文章