MVVMLight学习笔记(三)---数据双向绑定

一、概述

本文与其说是MVVMLight框架的学习,不如说是温故一下数据的双向绑定。

二、Demo

建立好MVVMLight框架后的Wpf工程后,建立一个Model。Model、View以及ViewModel的代码如下:

 1 using GalaSoft.MvvmLight;
 2 
 3 namespace MvvmLightDemo1.Model
 4 {
 5     public class WelcomeModel : ObservableObject
 6     {
 7         private string welcomeMsg;
 8         public string WelcomeMsg
 9         {
10             get { return welcomeMsg; }
11             set { welcomeMsg = value; RaisePropertyChanged(() => WelcomeMsg); }
12         }
13     }
14 
15 }
 1 using GalaSoft.MvvmLight;
 2 using MvvmLightDemo1.Model;
 3 
 4 namespace MvvmLightDemo1.ViewModel
 5 {
 6     public class MainViewModel : ViewModelBase
 7     {
 8         private WelcomeModel welcomeModel;
 9         public WelcomeModel WelcomeModel
10         {
11             get { return welcomeModel; }
12             set { welcomeModel = value; RaisePropertyChanged(() => WelcomeModel); }
13         }
14         /// <summary>
15         /// Initializes a new instance of the MainViewModel class.
16         /// </summary>
17         public MainViewModel()
18         {
19             WelcomeModel = new WelcomeModel() { WelcomeMsg = "Welcome to MVVMLight World!" };
20         }
21     }
22 }
 1 using CommonServiceLocator;
 2 using GalaSoft.MvvmLight.Ioc;
 3 
 4 namespace MvvmLightDemo1.ViewModel
 5 {
 6     /// <summary>
 7     /// This class contains static references to all the view models in the
 8     /// application and provides an entry point for the bindings.
 9     /// </summary>
10     public class ViewModelLocator
11     {
12         /// <summary>
13         /// Initializes a new instance of the ViewModelLocator class.
14         /// </summary>
15         public ViewModelLocator()
16         {
17             ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
18             SimpleIoc.Default.Register<MainViewModel>();
19         }
20 
21         public MainViewModel Main
22         {
23             get
24             {
25                 return ServiceLocator.Current.GetInstance<MainViewModel>();
26             }
27         }
28         
29         public static void Cleanup()
30         {
31             // TODO Clear the ViewModels
32         }
33     }
34 }
 1 <Window x:Class="MvvmLightDemo1.MainWindow"
 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:local="clr-namespace:MvvmLightDemo1"
 7         mc:Ignorable="d"
 8         Title="MVVMLIghtDemo1" Height="350" Width="525" Background="#FF699DC1">
 9     <Window.DataContext>
10         <Binding Path="Main" Source="{StaticResource Locator}"></Binding>
11     </Window.DataContext>
12     <Grid>
13         <StackPanel >
14             <TextBlock Text="{Binding WelcomeModel.WelcomeMsg}" FontSize="28" Foreground="#FFBB4913" HorizontalAlignment="Center"/>
15             <StackPanel Orientation="Horizontal">
16                 <Label Content="修改信息:" VerticalContentAlignment="Center" FontSize="20" Foreground="#FFC55D21"></Label>
17                 <TextBox Text="{Binding Path=WelcomeModel.WelcomeMsg,Mode=TwoWay}" FontSize="20" Foreground="#FFBB4913"/>
18                 <Button Content="LostFocus" Background="#FF22A658"></Button>
19             </StackPanel>
20         
21         </StackPanel>
22         <StackPanel VerticalAlignment="Top" HorizontalAlignment="Center" >
23   
24         </StackPanel>
25     </Grid>
26 </Window>

在View中,我们分别让一个TextBox和一个TextBlock绑定WelcomeModel中的WelcomeMsg属性
当我们在TextBox中输入文本的时候,利用双向绑定更新WelcomeModel中的WelcomeMsg属性,WelcomeMsg属性又通过RaisePropertyChanged来激发属性变更的事件,通知UI,如此一来,界面上的TextBlock中的内容就会更新。

但是,当我们运行以上程序的时候,修改TextBox里的内容,TextBlock中的内容并没有实时更新,而是需要按键盘上的Tab键或者点击LostFocus按钮,让TextBox失去焦点

这就引出了一个问题,当目标更新的时候,数据源是否更新以及更新的时机

为了解决这个问题,我们可以使用Binding的UpdateSourceTrigger和Mode属性

UpdateSourceTrigger属性的作用:当做何种改变的时候通知数据源我们做了改变,默认值是LostFocus,这就解释了为什么我们上述程序需要TextBox失去焦点的时候,TextBlock的内容才会更新。

UpdateSourceTrigger可以取以下值:

UpdateSourceTrigger取值
枚举类型 说明
Default 默认值(默认LostFocus)
Explicit 当应用程序调用 UpdateSource 方法时生效
LostFocus 失去焦点的时候触发
PropertyChanged 属性改变时立即触发

为了让TextBlock中的内容随着TextBox的内容实时变化,我们可以将绑定修改成如下格式:

 <TextBox Text="{Binding Path=WelcomeModel.WelcomeMsg,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" FontSize="20" Foreground="#FFBB4913"/>

Mode属性取值如下:

通过以上Demo,我们应达成以下共识:

1)ViewModel => View更新的时候,我们一般在属性的set块中加入RaisePropertyChanged,它的作用是当数据源改变的时候,会触发PropertyChanged事件,通知UI属性发生了变更;

2)View => ViewModel 更新的时候,我们一般利用BindingUpdateSourceTriggerMode属性。

原文地址:https://www.cnblogs.com/3xiaolonglong/p/10006966.html