WPF MVVMLight 3:双向数据绑定

上篇我们已经了解了MVVM的框架结构和运行原理。这里我们来看一下伟大的双向数据绑定。
说到双向绑定,大家比较熟悉的应该就是AngularJS了,几乎所有的AngularJS 系列教程的开篇几章都要涉及到,真的是很好用。
表达的效果很简单:就是在界面的操作对数据模型的修改能实时反映到数据;而数据的变更能实时展现到界面。即视图数据模型(ViewModel)和视图(View)之间的双向绑定和触发。
在这里插入图片描述
我们来操作一个试试看:
第一步:先写一个Model,里面包含我们需要的数据信息,代码如下:

/// <summary>
    /// 用户信息
    /// </summary>
    public class UserInfoModel : ObservableObject
    {
        private String userName;
        /// <summary>
        /// 用户名称
        /// </summary>
        public String UserName
        {
            get { return userName; }
            set { userName = value; RaisePropertyChanged(()=>UserName); }
        }

        private Int64 userPhone;
        /// <summary>
        /// 用户电话
        /// </summary>
        public Int64 UserPhone
        {
            get { return userPhone; }
            set { userPhone = value; RaisePropertyChanged(() => UserPhone); }
        }

        private Int32 userSex;
        /// <summary>
        /// 用户性别
        /// </summary>
        public Int32 UserSex
        {
            get { return userSex; }
            set { userSex = value; RaisePropertyChanged(()=>UserSex); }
        }

        private String userAdd;
        /// <summary>
        /// 用户地址
        /// </summary>
        public String UserAdd
        {
            get { return userAdd; }
            set { userAdd = value; RaisePropertyChanged(() => UserAdd); }
        }
    }

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

public class BothWayBindViewModel:ViewModelBase
    {
        public BothWayBindViewModel()
        {
            UserInfo = new UserInfoModel();
        }

        #region 属性

        private UserInfoModel userInfo;
        /// <summary>
        /// 用户信息
        /// </summary>
        public UserInfoModel UserInfo
        {
            get { return userInfo; }
            set { userInfo = value; RaisePropertyChanged(() => UserInfo); }
        }

        #endregion

        #region 命令
        #endregion
    }

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

/*
  In App.xaml:
  <Application.Resources>
      <vm:ViewModelLocator xmlns:vm="clr-namespace:MVVMLightDemo"
                           x:Key="Locator" />
  </Application.Resources>

  In the View:
  DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"

  You can also use Blend to do all this with the tool's support.
  See http://www.galasoft.ch/mvvm
*/

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;

namespace MVVMLightDemo.ViewModel
{
    /// <summary>
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// </summary>
    public class ViewModelLocator
    {
        /// <summary>
        /// Initializes a new instance of the ViewModelLocator class.
        /// </summary>
        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            #region Code Example
            if (ViewModelBase.IsInDesignModeStatic)
            {
                // Create design time view services and models
                SimpleIoc.Default.Register<IDataService, DesignDataService>();
            }
            else
            {
                // Create run time view services and models
                SimpleIoc.Default.Register<IDataService, DataService>();
            }
            #endregion

            SimpleIoc.Default.Register<MainViewModel>();
            SimpleIoc.Default.Register<WelcomeViewModel>();
            SimpleIoc.Default.Register<BothWayBindViewModel>();
        }

        #region 实例化
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }

        public WelcomeViewModel Welcome
        {
            get
            {
               return ServiceLocator.Current.GetInstance<WelcomeViewModel>();
            }
        }

        public BothWayBindViewModel BothWayBind
        {
            get
            {
                return ServiceLocator.Current.GetInstance<BothWayBindViewModel>();
            }
        }

        #endregion

        public static void Cleanup()
        {
            // TODO Clear the ViewModels
        }
    }
}

第四步:编写View:

<Window x:Class="MVVMLightDemo.View.BothWayBindView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding Source={StaticResource Locator},Path=BothWayBind}"
        Title="BothWayBindView" Height="300" Width="300">
    <Grid>
            <StackPanel Orientation="Vertical" Margin="10,10,0,0">
                <StackPanel Orientation="Horizontal" >
                    <TextBlock Text="请输入姓名:" ></TextBlock>
                    <TextBox Text="{Binding UserInfo.UserName,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Width="200" ></TextBox>
                </StackPanel>

                <StackPanel Margin="0,10,0,0" Orientation="Horizontal" >
                    <TextBlock Text="Hello " ></TextBlock>
                    <TextBlock Text="{Binding UserInfo.UserName}" ></TextBlock>
                </StackPanel>

                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" >
                </StackPanel>

            </StackPanel>
    </Grid>
</Window>

效果如图所示(当修改输入框的内容的时候,对应绑定数据相应改变,并触发对UI的修改,所以下面那行文字也相应改变改变。):
在这里插入图片描述
前面我们已经了解到了,RaisePropertyChanged的作用是当数据源改变的时候,会触发PropertyChanged事件达到通知UI更改的目的(ViewModel => View)。

那View上的变化要怎么通知到数据源呢:
View中文本框绑定内容如下:{Binding UserInfo.UserName,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay},
大家会看到多了两个属性,一个是UpdateSourceTrigger,一个是Mode属性。
UpdateSourceTrigger的作用是 当做何种改变的时候通知数据源我们做了改变。
在这里插入图片描述这边我们直接使用 PropertyChanged,当UI数据改变的时候,我们再通知到数据源去做修改。

还有一个属性就是Mode,他有五个参数:
在这里插入图片描述
这边明显有很多种选择,明确一点的是,我们是想把View上的变化同步到ViewModel(Target => Source),所以使用OneWayToSource、TwoWay、Default或者不写都可以。
严谨点应该使用OneWayToSource。因为是文本框,属于可以编辑控件,所以 Default指向的是TwoWay。
下面还有一个TextBlock,仅仅用于显示的,所以不需要目标对源的修改,无需指定就默认是OneWay,当源改变的时候,会通知它进行修改。
点击下载源码

PS:本文转载自博客园的作者Brand的原创文章,感谢原作者的分享。原文链接:https://www.cnblogs.com/wzh2010/p/6286923.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值