1.1绑定到对象

1.1.1、前台绑定

前台代码

   5:  </Grid>
   1:  <Grid x:Name=”GridProductDetails”>
   2:   
   3:  <TextBox Grid.Column="1"  x:Name="txtModelNum" Text="{ Binding Path=ModelNumber}"/>
   4:   

对应后台代码

   1:  Model_Product BP = new BLL_Product().GetProduct(123);
   2:  GridProductDetails.DataContext = BP;

1.1.2、后台绑定

前台代码

   1:  <Grid x:Name=”GridProductDetails”>
   2:       <TextBox Grid.Column="1"  x:Name="txtModelNum" />
   3:  </Grid>

对应后台代码

   1:  Binding B = new Binding(); 
   2:  B.Source=BP; 
   3:  B.Path = new PropertyPath("ModelNumber"); 
   4:  txtModelNum.SetBinding(TextBox.TextProperty, B);

1.2 绑定到控件

有一列表框控件ListBox绑定到一个List<Product> 数据源,显示项为Product对象的ModelName属性,前台代码如下

   1:  <ListBox Name="lstProducts" Margin="5" DisplayMemberPath="ModelName"
   2:                SelectionChanged="lstProducts_SelectionChanged">                
   3:  </ListBox>

对应后台代码为

   1:  private ICollection<Product> products;
   2:  products = App.StoreDb.GetProducts();
   3:  lstProducts.ItemsSource = products;

现在将一个Grid里面的一系列控件绑定到ListBox所选择的数据项上,用于构建“主--详细信息”的显示结构,代码如下

   1:  <Grid DataContext="{Binding ElementName=lstProducts, Path=SelectedItem}" TextBox.TextChanged="txt_TextChanged">
   2:  <TextBox Margin="5"  Text="{Binding Path=ModelNumber}"></TextBox>
   3:  </Grid>

1.3 绑定的双向更新

1.3.1 对象和控件的双向更新

双向更新:即修改对象的属性值后,对应的前台控件自动更新为修改后的值。

前台无需做任何修改,只需在对象类Model定义的时候实现INotifyPropertyChanged接口即可:

   1:  public class Model_Product : INotifyPropertyChanged
   2:    {
   3:        string modelNumber;
   4:   
   5:        public string ModelNumber
   6:        {
   7:            get { return modelNumber; }
   8:            set
   9:            {
  10:                modelNumber = value;
  11:                OnPropertyChanged(new PropertyChangedEventArgs("ModelNumber"));
  12:            }
  13:        }
  14:   
  15:        int _ID;
  16:        public int ID
  17:        {
  18:            get { return _ID; }
  19:            set { _ID = value; }
  20:        }
  21:        /// <summary>
  22:        /// 实现INotifyPropertyChanged接口 可以实现控件值和对象属性值的自动绑定 当修改对象值后 控件的值自动刷新
  23:        /// </summary>
  24:        public event PropertyChangedEventHandler PropertyChanged;
  25:        public void OnPropertyChanged(PropertyChangedEventArgs e)
  26:        {
  27:            if (PropertyChanged != null)
  28:                PropertyChanged(this, e);
  29:        }
  30:    }
  31:   
 

1.3.2 绑定到对象集合(类似于List<T>)的双向更新

 

双向更新:即修改对象的属性值后,对应的前台控件自动更新为修改后的值

无需些多少代码,只需把数据集合申明为实现了INotifyPropertyChanged接口的集合类型就可以了,在WPF中这个常用的有ObservableCollection<T>这个泛型集合类,如果是WindosForm编程,有个BindingList集合(实现了IBingdingList接口)

   1:  public ICollection<Product> GetProducts()
   2:  {
   3:      DataSet ds = StoreDbDataSet.ReadDataSet();
   4:   
   5:      ObservableCollection<Product> products = new ObservableCollection<Product>();
   6:      foreach (DataRow productRow in ds.Tables["Products"].Rows)
   7:      {
   8:          products.Add(new Product((string)productRow["ModelNumber"],
   9:              (string)productRow["ModelName"], (decimal)productRow["UnitCost"],
  10:              (string)productRow["Description"], (int)productRow["CategoryID"],
  11:              (string)productRow["CategoryName"], (string)productRow["ProductImage"]));
  12:      }
  13:      return products;
  14:  }

1.4 绑定到ADO.NET数据集 DataSet

Controls.ItemsSource=DateSetObject.Tables[n].DefaultView;

需要注明Controls的DisplayMemberPath属性

删除数据集行建议采取的方法

((DataRowView)lstProducts.SelectedItem).Row.Delete();

1.5 绑定到LINQ集合

   1:  public ICollection<Product> GetProductsFilteredWithLinq(decimal minimumCost)
   2:  {
   3:      // Get the full list of products.
   4:      ICollection<Product> products = GetProducts();
   5:   
   6:      // Create a second collection with matching products.
   7:      IEnumerable<Product> matches = from product in products
   8:                                      where product.UnitCost >= minimumCost
   9:                                      select product;
  10:   
  11:      return new ObservableCollection<Product>(matches.ToList());
  12:  }

此处采用public ObservableCollection(List<T> list)实现对LINQ结果集的转换以实现双向更新:即修改对象的属性值后,对应的前台控件自动更新为修改后的值。

1.6 绑定验证

前台代码:

   1:  <Window x:Class="WPFGameTest.DataBinding.TestOfValidationRules"
   2:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:          Title="TestOfValidationRules" Height="300" Width="300">
   5:      <StackPanel >
   6:          
   7:          <TextBox x:Name="textBox1" Margin="5" />
   8:          
   9:          <Slider x:Name="slider1" Minimum="-10" Maximum="110" Margin="5" />
  10:                  
  11:   
  12:      </StackPanel>
  13:   
  14:  </Window>

后台代码

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Threading.Tasks;
   6:  using System.Windows;
   7:  using System.Windows.Controls;
   8:  using System.Windows.Data;
   9:  using System.Windows.Documents;
  10:  using System.Windows.Input;
  11:  using System.Windows.Media;
  12:  using System.Windows.Media.Imaging;
  13:  using System.Windows.Shapes;
  14:   
  15:  namespace WPFGameTest.DataBinding
  16:  {
  17:      /// <summary>
  18:      /// TestOfValidationRules.xaml 的交互逻辑
  19:      /// </summary>
  20:      public partial class TestOfValidationRules : Window
  21:      {
  22:          public TestOfValidationRules()
  23:          {
  24:               InitializeComponent();  
  25:   
  26:            Binding binding = new Binding("Value")  
  27:            {  
  28:                 Source = this.slider1  
  29:            };  
  30:   
  31:            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;  
  32:              
  33:            RangeValidateRule rvr = new RangeValidateRule();  
  34:            rvr.ValidatesOnTargetUpdated = true;  
  35:            binding.ValidationRules.Add(rvr);  
  36:   
  37:            binding.NotifyOnValidationError = true;  
  38:            this.textBox1.SetBinding(TextBox.TextProperty, binding);  
  39:  

this.textBox1.AddHandler(Validation.ErrorEvent,new RoutedEventHandler(this.ValidationError));

  40:   
  41:          }
  42:          void ValidationError(object sender, RoutedEventArgs e)  
  43:         {
  44:             Control C = sender as Control;
  45:   
  46:             if (Validation.GetErrors(C).Count > 0)
  47:             {
  48:                 (C).Background = new SolidColorBrush(Colors.Red);
  49:                 C.ToolTip = Validation.GetErrors(C)[0].ErrorContent.ToString();
  50:             }
  51:             else
  52:             {
  53:                 (C).Background = new SolidColorBrush(Colors.White);
  54:                 C.ToolTip = null;
  55:             }
  56:   
  57:         }  
  58:   
  59:      }
  60:      public class RangeValidateRule:ValidationRule  
  61:     {  
  62:         public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)  
  63:         {  
  64:             double d = 0;  
  65:             if (double.TryParse(value.ToString(),out d))  
  66:             {  
  67:                 if(d >= 0 && d <= 100)  
  68:                 {  
  69:                     return new ValidationResult(true,null);  
  70:                 }  
  71:             }  
  72:   
  73:             return new ValidationResult(false,"Validation Failed !!!");  
  74:         }  
  75:     }  
  76:   
  77:  }

要点在第39行,为一个附加事件,关于附加事件可以参考http://msdn.microsoft.com/zh-cn/library/ms598899(v=VS.95).aspx

另外还有个衍生知识要点是“扩展方法”,这两个应该属于高级一点的编程特性,扩展方法请参照http://msdn.microsoft.com/zh-cn/library/vstudio/bb383977.aspx

1.6.1 注意e.Action == ValidationErrorEventAction.Removed

注意:在值一改变就验证的模式中,不可以用下面的代码方式来处理验证信息。因为当发生一个验证错误时,此时的xe.Action 值为 ValidationErrorEventAction.Added, 代码执行到第10行后跳出ValidationError方法。

此时系统会认为错误验证已经被处理,就会自动再次执行ValidationError,而此时的xe.Action 值为 ValidationErrorEventAction.Removed。

所以使用此方法用于验证,会出现看不到红色背景的效果。

MSDN是这样解释的:

如果发生验证错误,绑定引擎将引发 BindingValidationError 事件。 ValidationError  传递到包含一个新 Exception 的事件处理程序,且 Action 值为 Added。

如果该验证错误得到解决(极有可能是用户通过使用验证信息对项进行更新来解决的),则相同的 ValidationError 将传递到包含原始异常的事件处理程序,且 Action 值为 Removed。

http://msdn.microsoft.com/zh-cn/library/system.windows.controls.validationerroreventaction(v=vs.95).aspx

次验证方法适合于有提交按钮的情况,当点击提交按钮后执行下面的验证。

   1:  void ValidationError(object sender, RoutedEventArgs e)
   2:          {
   3:              Control C = sender as Control;
   4:              ValidationErrorEventArgs xe = e as ValidationErrorEventArgs;
   5:              if (xe.Action == ValidationErrorEventAction.Added )
   6:              {
   7:                  if (Validation.GetErrors(C).Count > 0)
   8:                  {
   9:                      (C).Background = new SolidColorBrush(Colors.Red);
  10:                      C.ToolTip = Validation.GetErrors(C)[0].ErrorContent.ToString();
  11:                  }
  12:              }
  13:              if (xe.Action == ValidationErrorEventAction.Removed)
  14:              {
  15:                  (C).Background = new SolidColorBrush(Colors.White);
  16:              }
  17:   
  18:          }

1.6.2 使用绑定组来验证

   1:  GridProductDetails.DataContext = BP;
   2:  BindingGroup bin = new System.Windows.Data.BindingGroup();
   3:  bin.Name = "bb";
   4:  GridProductDetails.BindingGroup = bin;
   5:  GridProductDetails.BindingGroup.BeginEdit();
   6:   
   7:   
   8:  PositivePriceRule rule = new PositivePriceRule();
   9:  rule.Max = 300;
  10:   
  11:   
  12:  Binding B = new Binding();
  13:  B.Source = BP;
  14:  B.Path = new PropertyPath("ID");//
  15:  B.NotifyOnValidationError = true;
  16:  B.ValidatesOnExceptions = true;
  17:  B.Mode = BindingMode.TwoWay;
  18:  B.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
  19:  B.ValidationRules.Add(rule);
  20:  

B.BindingGroupName = bin.Name;

  21:   
  22:  txtModelNum.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.ValidationError));
  23:  txtModelNum.SetBinding(TextBox.TextProperty, B);

关键的代码在第20行,通过指定Binding对象的BindingGroupName 属性来关联Binding对象到BindingGroup组里面。

此番修改以后,如果出现错误,使用BindingGroup的控件(第4行GridProductDetails.BindingGroup = bin)的边框就会变为红色。

WPF 数据绑定的更多相关文章

  1. WPF 数据绑定Binding

    什么是数据绑定? Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简单而一致的方法来显示数据以及与数据交互. 通过数据绑定,您可以对两个不同对象 ...

  2. WPF数据绑定Binding(二)

    WPF数据绑定Binding(二) 1.UI控件直接的数据绑定 UI对象间的绑定,也是最基本的形式,通常是将源对象Source的某个属性值绑定 (拷贝) 到目标对象Destination的某个属性上. ...

  3. WPF——数据绑定(一)什么是数据绑定

    注意:本人初学WPF,文中可能有表达或者技术性问题,欢迎指正!谢谢! 一:什么是数据绑定? “Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简 ...

  4. 剖析WPF数据绑定机制

    引言 WPF框架采取的是MVVM模式,也就是数据驱动UI,UI控件(Controls)被严格地限制在表示层内,不会参与业务逻辑的处理,只是通过数据绑定(Data Binding)简单忠实地表达与之绑定 ...

  5. WPF 10天修炼 第十天- WPF数据绑定

    WPF数据绑定 数据绑定到元素属性是将源对象指定为一个WPF元素,并且源属性是一个依赖属性,依赖属性内置了变更通知.当改变源对象依赖属性值之后,绑定目标可以立即得到更新,开发人员不需要手动编写响应事件 ...

  6. 微软原文翻译:适用于.Net Core的WPF数据绑定概述

    原文链接,大部分是机器翻译,仅做了小部分修改.英.中文对照,看不懂的看英文. Data binding overview in WPF 2019/09/19 Data binding in Windo ...

  7. C#-WPF数据绑定基础(一)

    前言:WPF数据绑定技术有效的提高了程序的容错率,可以最大程度的保持程序的健壮性,从而降低程序在使用过程中崩掉的可能性. 接下来,我将分享一下我在写测量程序过程中所用到的数据绑定方面的知识 首先,我所 ...

  8. C#WPF数据绑定模板化操作四步走

    前言:WPF数据绑定对于WPF应用程序来说尤为重要,本文将讲述使用MVVM模式进行数据绑定的四步走用法: 具体实例代码如下: 以下代码仅供参考,如有问题请在评论区留言,谢谢 1 第一步:声明一个类用来 ...

  9. WPF 数据绑定 1_1 基础知识&绑定到元素属性

    A.数据绑定基础: 数据源对象:WPF将从该对象中提取信息,交由目标对象进行显示. 目标对象:从数据源中提取信息,并赋给该对象的属性. B.绑定到元素属性 最简单的绑定情形则是将一个源对象指定为一个W ...

  10. WPF 数据绑定基础

    纯理论,可能会枯燥. .net 技术群: 199281001 ,欢迎加入. 1.目标对象一定是派生自DependencyObject的对象,并且目标属性必须是依赖属性,否则数据绑定操作将会失   败. ...

随机推荐

  1. 纯 CSS 创建一个三角形

    [要求]:用纯CSS创建一个三角形的原理是什么? ♪ 答: 把上.左.右三条边隐藏掉(颜色设为 transparent) [实现]: #demo { width: 0; height: 0; bord ...

  2. 递归---n皇后

    ---恢复内容开始--- #include "stdafx.h" #include <iostream> #include <fstream> //文件流 ...

  3. Alice and Bob

    类似于石子合并的游戏,在黑板上写下N个数,每次只能将其中的一个数减1(结果为0自动消去),或者将某两个数消去,将其和写在黑板上. Alice先手,彼此都采用最优策略,将最后一个数消去者获胜. 思路:设 ...

  4. [转载] C++ typedef 用法详解

    typedef的语法描述 在现实生活中,信息的概念可能是长度,数量和面积等.在C语言中,信息被抽象为int.float和 double等基本数据类型.从基本数据类型名称上,不能够看出其所代表的物理属性 ...

  5. Codeforces Round #260 (Div. 2) A B C 水 找规律(大数对小数取模) dp

    A. Laptops time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  6. iPhone4@iOS7Beta4,第一时间刷上,失望,看来苹果是铁了心往扁平化UI走了。看好我的614,保存好SHSH准备

    1 今天早上看到新闻,iOS7Beta4放出了,于是赶紧,在家下载,网速很快.(要是在公司,那50K的速度,估计会疯的) 2 等了一会儿一直在提示准备安装,不等了,再等该迟到了. 3 路上实在忍不住, ...

  7. ASP.NET Web API与Rest web api:发布到IIS(二)(同发布.NET webservice)

    本文档大部分来源于:http://www.cnblogs.com/zqzjs/p/4705994.html 工具VS2010,window环境win7 一:Webservice的创建与方法查看调用 1 ...

  8. ExtJS参考手册

    ExtJS是一个用javascript写的,主要用于创建前端用户界面,是一个与后台技术无关的前端ajax框架.因此,可以把ExtJS用在.Net.Java.Php等各种开发语言开发的应用中.ExtJs ...

  9. thinkphp3.2 学习

    http://www.tuicool.com/articles/nQFnQrR 1,sublime text 增强插件 右键可以打开文件目录 http://www.w3cfuns.com/notes/ ...

  10. eclipse启动不了,让查看.metadata/.log

    方法一: 下面是workspace E:\kuaipan\work\J2EE_workspace\.metadata\.plugins\org.eclipse.core.resources\.proj ...