WPF 数据绑定
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。
次验证方法适合于有提交按钮的情况,当点击提交按钮后执行下面的验证。
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 数据绑定的更多相关文章
- WPF 数据绑定Binding
什么是数据绑定? Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简单而一致的方法来显示数据以及与数据交互. 通过数据绑定,您可以对两个不同对象 ...
- WPF数据绑定Binding(二)
WPF数据绑定Binding(二) 1.UI控件直接的数据绑定 UI对象间的绑定,也是最基本的形式,通常是将源对象Source的某个属性值绑定 (拷贝) 到目标对象Destination的某个属性上. ...
- WPF——数据绑定(一)什么是数据绑定
注意:本人初学WPF,文中可能有表达或者技术性问题,欢迎指正!谢谢! 一:什么是数据绑定? “Windows Presentation Foundation (WPF) 数据绑定为应用程序提供了一种简 ...
- 剖析WPF数据绑定机制
引言 WPF框架采取的是MVVM模式,也就是数据驱动UI,UI控件(Controls)被严格地限制在表示层内,不会参与业务逻辑的处理,只是通过数据绑定(Data Binding)简单忠实地表达与之绑定 ...
- WPF 10天修炼 第十天- WPF数据绑定
WPF数据绑定 数据绑定到元素属性是将源对象指定为一个WPF元素,并且源属性是一个依赖属性,依赖属性内置了变更通知.当改变源对象依赖属性值之后,绑定目标可以立即得到更新,开发人员不需要手动编写响应事件 ...
- 微软原文翻译:适用于.Net Core的WPF数据绑定概述
原文链接,大部分是机器翻译,仅做了小部分修改.英.中文对照,看不懂的看英文. Data binding overview in WPF 2019/09/19 Data binding in Windo ...
- C#-WPF数据绑定基础(一)
前言:WPF数据绑定技术有效的提高了程序的容错率,可以最大程度的保持程序的健壮性,从而降低程序在使用过程中崩掉的可能性. 接下来,我将分享一下我在写测量程序过程中所用到的数据绑定方面的知识 首先,我所 ...
- C#WPF数据绑定模板化操作四步走
前言:WPF数据绑定对于WPF应用程序来说尤为重要,本文将讲述使用MVVM模式进行数据绑定的四步走用法: 具体实例代码如下: 以下代码仅供参考,如有问题请在评论区留言,谢谢 1 第一步:声明一个类用来 ...
- WPF 数据绑定 1_1 基础知识&绑定到元素属性
A.数据绑定基础: 数据源对象:WPF将从该对象中提取信息,交由目标对象进行显示. 目标对象:从数据源中提取信息,并赋给该对象的属性. B.绑定到元素属性 最简单的绑定情形则是将一个源对象指定为一个W ...
- WPF 数据绑定基础
纯理论,可能会枯燥. .net 技术群: 199281001 ,欢迎加入. 1.目标对象一定是派生自DependencyObject的对象,并且目标属性必须是依赖属性,否则数据绑定操作将会失 败. ...
随机推荐
- notebook
1. 2.
- win7将 esc与 capslock 互换
一天手软,于是买了一个机械键盘.cherry g80-3494 红轴各方面都不错就是有一个问题我经常用vim,其中esc.及F键区离主键盘区实在是太远了. 习惯于vim模式的人都有一种懒症,就是手指非 ...
- ANTLR3完全参考指南读书笔记[07]
前言 真正意义上的程序员都很懒,懒的连多余的一行代码也不写. 如果能将底层满手油污的活儿都可以交给别人去做,自己就扮演个智囊团成员的角色,生活会比想象中的还要惬意. 严格的按照指令执行长时间不知疲倦的 ...
- db2 字符串转换 数字
今天使用聚合函数的时候 发现 varchar类型的是不可用的,所以呢就开始想办法解决 用到了转换函数cast(s.score as bigint) 然后有一个问题就是如果数据为空的话就会发生转换错误. ...
- 209. Minimum Size Subarray Sum
Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...
- 350. Intersection of Two Arrays II
Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, 2, 1] ...
- 在ros中使用rplidar Laser发布scan数据--25
原创博客:转载请表明出处:http://www.cnblogs.com/zxouxuewei/ 由于市面上买的激光雷达价格太贵了.所以在学习时会造成很大的经济压力.但是最近好多做机器人核心组件的公司都 ...
- MySQL性能优化之max_connections配置参数浅析
这篇文章主要介绍了MySQL性能优化之max_connections配置参数浅析,本文着重讲解了3种配置max_connections参数的方法,需要的朋友可以参考下 MySQL的max_connec ...
- 【P1304】【P1305】选课与选课输出方案
多叉树归 原题: 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<500)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这M门课并考核 ...
- Java——java多态
/* * 多态: * 成员的特点: * 1.成员变量. * 编译时:参开引用型变量所属类中的是否有调用的成员变量, 有:编译通过, 没有 编译失败. * 运行时: 参考引用变量所属的类 ...