绑定(Binding)是WPF提供的一个非常方便的特性,它可以方便的实现一个WPF的MVVM结构。

既可以实现数据驱动UI变化,也可以做到End-user在UI上的修改实现的反映到数据上。

但是有一点必须注意的是:WPF的数据基本上都是使用的引用类型,引用类型的特性就是在传递过程中,数据本体是没有变化的。

可能你对数据进行了几次不经意的传递后,对变量做的修改竟然体现在了UI的变化。这时,Debug又变成了一件很痛苦的事情(尤其是当项目比较庞大的时候)。

首先来看一个比较常见的例子。

我有一个如上图的UI,左边一个ListView,右边有一个TextBox用于编辑,代码如下:

 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Runtime.CompilerServices;
 using System.Windows;

 namespace WpfApplication2
 {
     /// <summary>
     /// Interaction logic for MainWindow.xaml
     /// </summary>
     public partial class MainWindow : Window
     {
         private MainViewModel FViewModel = null;
         public MainViewModel ViewModel
         {
             get { return FViewModel; }
             set
             {
                 if (value != FViewModel)
                     FViewModel = value;
             }
         }
         public MainWindow()
         {
             InitializeComponent();

             FViewModel = new MainViewModel();

             this.DataContext = ViewModel;
         }
     }

     public class MainViewModel : INotifyPropertyChanged
     {
         public MainViewModel()
         {
             DataModels = new ObservableCollection<MainDataModel>(BuildHardCodeList());
         }

         public event PropertyChangedEventHandler PropertyChanged;
         private void RaisePropertyChanged([CallerMemberName] string aMembName = "")
         {
             if (PropertyChanged != null)
             {
                 PropertyChanged(this, new PropertyChangedEventArgs(aMembName));
             }
         }

         private static IEnumerable<MainDataModel> BuildHardCodeList()
         {
             yield return new MainDataModel() { Name = "DataModel - 1" };
             yield return new MainDataModel() { Name = "DataModel - 2" };
             yield return new MainDataModel() { Name = "DataModel - 3" };
             yield return new MainDataModel() { Name = "DataModel - 4" };
             yield return new MainDataModel() { Name = "DataModel - 5" };
         }

         public ObservableCollection<MainDataModel> DataModels { get; set; }

         private MainDataModel FCurrentDataModel;
         public MainDataModel CurrentDataModel
         {
             get { return FCurrentDataModel; }
             set
             {
                 if (value != FCurrentDataModel)
                 {
                     FCurrentDataModel = value;
                     RaisePropertyChanged();
                 }
             }
         }
     }
     public class MainDataModel
     {
         public string Name { get; set; }

         public override string ToString()
         {
             return Name;
         }
     }
 }

实际运行起来后,我选中了一行以后,Name-TextBox用选中的item的Name进行了填充。

我修改了Name的内容,鼠标移到下一个TextBox。

这时发现ListView的相应记录也修改了。这就是引用类型产生的作用。

其时在大部分情况下,我们是不希望ListView的内容进行改变,直到我点击Save button。

要想实现这个需求就必须把CurrentDataModel与DataModels的连接打断掉。

现在DataModel - 1的数据存储方式如上图,堆栈中只有一份DataModel - 1, ListView与TextBox全都引用这一份数据,当TextBox进行修改时,这唯一的一份数据进行了修改,当然就会更新ListView。

要打断这种引用关系,就需要对DataModel - 1进行一次深拷贝(注意:一定是深拷贝,否则又只是一次简单的引用关系),数据的连接关系都通过深拷贝来实现,它们的关系如下图:

具体实现晚些时候有时间再放上... ...

注意WPF中绑定使用的是引用类型的更多相关文章

  1. 从0 开始 WPF MVVM 企业级框架实现与说明 ---- 第二讲 WPF中 绑定

    说到WPF, 当然得从绑定说起,这也是WPF做的很成功的一个地方,这也是现在大家伙都在抛弃使用winform的其中一个主要原因,Binding这个东西从早说到完其实都说不完的,我先就做一些基本的介绍, ...

  2. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  3. MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  4. WPF中Image控件绑定到自定义类属性

    首先我们定义一个Student类,有ID,Name,Photo(保存图片路径). using System; using System.Collections.Generic; using Syste ...

  5. WPF窗体视图中绑定Resources文件中字符串时,抛出:System.Windows.Markup.StaticExtension

    问题描述: 在Resources.resx定义了一个静态字符串字段Title,并在WPF窗体视图中绑定为窗体的标题: Title="{x:Static local:Resources.Tit ...

  6. WPF中PasswordBox控件无法绑定Password属性解决办法

    在WPF中,默认的Password控件的Password属性是不允许为之绑定的,下面是一个解决绑定Password的方法的代码: 1.前台代码 <Window x:Class="Pas ...

  7. WPF 在事件中绑定命令(不可以在模版中绑定命令)

    其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实现将命令绑定到事件中. 上一篇中我们介绍了MVVMLight中的命令的用法,那么仅仅知道命令是 ...

  8. WPF中在MVVM模式下,后台绑定ListCollectionView事件触发问题

    问题:WPF中MVVM模式下 ListView绑定ListCollectionView时,CurrentChanged无法触发 解决方案: 初期方案:利用ListView的SelectionChang ...

  9. MVVM设计模式和在WPF中的实现(四) 事件绑定

    系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中的实现(三)命令绑定 MVVM模式解析和在WPF中的 ...

随机推荐

  1. TCP Socket 通讯(客户端与服务端)

    /*----------------------------编译环境:VS2015---------------------------------------*/ /*--------------- ...

  2. mongodb的linux环境搭建

    一.启动 [mongodb@node1 ~]$ mongod -f /data/config/shard1.confmongod: /usr/lib64/libcrypto.so.10: no ver ...

  3. ajax提交复杂对象数据

    public class RouteItemManageReq { private List<WorkNodeReq> targetNodes; private RouteItemReq ...

  4. 【转】Linux Soclet编程

    原文地址:http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编 ...

  5. CodeSmith和PowerDesigner的使用安装和数据库创建

    原文链接: http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html 废话少说,开始我们的CodeSmith旅程吧,我先讲讲这个 ...

  6. []cp,转载]提示MyEclipse Trial Expired,如何手动获取MyEclipse 注册码!很牛!

    1.建立JAVA Project,随便命名,只要符合规则就行. 2.在刚刚建好的Project右击src,新建一个类,命名为MyEclipseGen,把.java里本来有的代码全部删掉,再把下面的代码 ...

  7. Record Locks

    Record Locks 记录锁: 记录锁是一个锁在一个Index记录上,比如 SELECT c1 FOR UPDATE FROM t WHERE c1 = 10; 阻止任何其他事务inserting ...

  8. c#params应用

    params 是C#开发语言中关键字, params主要的用处是在给函数传参数的时候用,就是当函数的参数不固定的时候. 在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允 ...

  9. gRPC实战

    gRPC是Google开源的一款非常棒的系统间通信工具,完美的communication抽象,构建在protobuf之上的RPC. 下面我们聊聊它的应用场景,grpc为分布式系统而生,可以是系统间通信 ...

  10. request内置对象

    request内置对象(JSP九大内置对象之一)简述:内置对象即已在容器内部创建完成,可以直接调用的对象.容器在接收到客户端的请求后会创建一个对象用于处理请求信息,该对象就是内置对象(属于“javax ...