zoukankan      html  css  js  c++  java
  • 注意WPF中绑定使用的是引用类型

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

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

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

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

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

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

     1 using System.Collections.Generic;
     2 using System.Collections.ObjectModel;
     3 using System.ComponentModel;
     4 using System.Runtime.CompilerServices;
     5 using System.Windows;
     6 
     7 namespace WpfApplication2
     8 {
     9     /// <summary>
    10     /// Interaction logic for MainWindow.xaml
    11     /// </summary>
    12     public partial class MainWindow : Window
    13     {
    14         private MainViewModel FViewModel = null;
    15         public MainViewModel ViewModel
    16         {
    17             get { return FViewModel; }
    18             set
    19             {
    20                 if (value != FViewModel)
    21                     FViewModel = value;
    22             }
    23         }
    24         public MainWindow()
    25         {
    26             InitializeComponent();
    27 
    28             FViewModel = new MainViewModel();
    29 
    30             this.DataContext = ViewModel;
    31         }
    32     }
    33 
    34     public class MainViewModel : INotifyPropertyChanged
    35     {
    36         public MainViewModel()
    37         {
    38             DataModels = new ObservableCollection<MainDataModel>(BuildHardCodeList());
    39         }
    40 
    41         public event PropertyChangedEventHandler PropertyChanged;
    42         private void RaisePropertyChanged([CallerMemberName] string aMembName = "")
    43         {
    44             if (PropertyChanged != null)
    45             {
    46                 PropertyChanged(this, new PropertyChangedEventArgs(aMembName));
    47             }
    48         }
    49 
    50         private static IEnumerable<MainDataModel> BuildHardCodeList()
    51         {
    52             yield return new MainDataModel() { Name = "DataModel - 1" };
    53             yield return new MainDataModel() { Name = "DataModel - 2" };
    54             yield return new MainDataModel() { Name = "DataModel - 3" };
    55             yield return new MainDataModel() { Name = "DataModel - 4" };
    56             yield return new MainDataModel() { Name = "DataModel - 5" };
    57         }
    58 
    59         public ObservableCollection<MainDataModel> DataModels { get; set; }
    60 
    61         private MainDataModel FCurrentDataModel;
    62         public MainDataModel CurrentDataModel
    63         {
    64             get { return FCurrentDataModel; }
    65             set
    66             {
    67                 if (value != FCurrentDataModel)
    68                 {
    69                     FCurrentDataModel = value;
    70                     RaisePropertyChanged();
    71                 }
    72             }
    73         }
    74     }
    75     public class MainDataModel
    76     {
    77         public string Name { get; set; }
    78 
    79         public override string ToString()
    80         {
    81             return Name;
    82         }
    83     }
    84 }
    View Code

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

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

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

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

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

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

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

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

  • 相关阅读:
    Luogu p2672 推销员 (贪心)
    HDU 1548 A strange lift (暴力搜索)
    HDU 1258 Sum it up (dfs)
    HDU 1087 FatMouse and Cheese (记忆化搜索)
    Beautiful Numbers(牛客)
    E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂)
    Super A^B mod C FZU
    bitset入门 简单瞎搞题
    D. Dirty Deeds Done Dirt Cheap(思维)
    大家一起来数二叉树吧(DP)
  • 原文地址:https://www.cnblogs.com/larson/p/5822287.html
Copyright © 2011-2022 走看看