博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF之Binding
阅读量:5234 次
发布时间:2019-06-14

本文共 6646 字,大约阅读时间需要 22 分钟。

wpf致力于将业务逻辑层处于核心地位,展示层永远处于逻辑层的从属位置wpf的这种能力源于DataBinding 、与之配套的Dependency Property系统和DataTemplateTarget  <=>  Binding  <=>  SourceBinding的源:也就是数据的源头,只要求是个对象并通过属性公开自己的数据,它就能作为Binding源例如:1.把控件自己或者自己的容器或子级元素作为源2.用一个控件作为另一个控件的源3.把集合作为ItemsControl的数据源4.使用XML作为TreeView或Menu的数据源5.把多个控件关联到一个“数据制高点”上,甚至不给Binding指定数据源让它自己去找。控制Binding的方向和数据的更新控制Binding数据流向的属性是Model,它的类型是BindingModelBindingModel枚举TwoWayOneWayOnTimeOneWayToSourceDefault 根据实际情况来定,可编辑的双向,只读的单向Binding数据更新的属性是UpdateSourceTrigger枚举PropertyChangedLostFocusExplicitDefault另Binding还有一个属性NotifyOnSourceUpdated、NotifyOnTargetUpdated两个bool属性如果设为true,当源或目标更新时会激发相应的SourceUpdated事件和TargetUpdated事件Binding的路径Path来关注源中哪个属性的值,由path来指定,可以在Binding的构造器来指定,Path的实际类型是PropertyPath我们知道用一个控件可以作为另一个控件的源Path可以用来关注属性,而属性又分为无参属性、有参属性(索引器)针对于有参属性例如:textBox2显示textBox1的第四个文本字符。
当一个集合或DataView作为源时,如果想默认的元素当做Path使用,需要这样的语法List
list=new List
(){
"Tom","Tim","Blog"};this.textBox1.SetBinding(TextBox.TextProperty,new Binding("/"){ Source=list}); //Tomthis.textBox2.SetBinding(TextBox.TextProperty,new Binding("/Length"){ Source=list}); //3this.textBox3.SetBinding(TextBox.TextProperty,new Binding("/[2]"){ Source=list}); //m如果想把子集合中的元素当做Path,可以使用多级斜线的语法没有Path的Binding实例本身就是数据源,不需要Path来指明,例如string int等基本类型就是,实例本身就是数据,无法通过哪个属性来访问数据例如:
实例本身就是数据源
Path可以省略掉为Binding指定Path的几种方法1、普通CLR类型单个对象指定为Source:包括FCL类型和用户自定义类型的对象,如果该类型实现了INotifyPropertyChanged接口,则可通过在属性的set语句里激发PropertyChanged事件来通知Binding数据已被更新。2、数组、List
、ObservableCollection
等集合类型,一般是把控件的ItemsSource属性使用Binding关联到一个集合对象上。3、ADO.Net的对象DataTable和DataView对象4、XmlDataProvider把XML指定为Source ,如TreeView、Menu 上上节提到的x:XData指令元素5、把依赖对象指定为Source6、把容器的DataContext设为Source,只设置Path,不设置Source,让这个Binding自己去找Source(会沿着控件树一层一层向外找,直到找到带有path指定属性的对象为止)7、通过ElementName指定Source8、通过Binding的RelativeSource属性相对的指定Source:当控件想关注自己的、自己容器的或者自己内部元素的某个值时采用这种办法。9、把ObjectDataProvider对象指定为Source:当数据源不是通过属性而是通过方法暴漏给外界的时候10、使用Linq检索的数据对象作为Binding的源。一一介绍:6、没有Source的Binding——使用DataContext作为Binding的源Binding就会自动向UI元素树的上层去寻找可用的DataContext如下代码:
当实例本身就是数据源时,Path=.,可以没有path,如果某个DataContext是个简单类型对象时,也可以不指定Source如下代码:
Hello DataContext!!
Binding沿着UI元素向上找,其实Binding没有那么智能,只是DataContext是一个依赖属性这里依赖属性很重要的一个特点是:当你没有为控件的某个依赖属性显示赋值时,控件会把自己容器的属性值借过来当做自己的属性值实际工作中DataContext的用法非常灵活:(1)、当UI上的多个控件使用Binding关注同一个对象时,可以使用DataContext。(2)、当作为Source的对象不能被直接访问时——比如B窗体的控件想把A窗体的控件当做自己的Binding源时,但A窗体的控件是private访问级别,这时候就可以把这个控件(控件的值)作为A窗体的DataContext(这个属性石public访问级别)从而暴漏出来2、使用集合对象作为列表控件的ItemsSource使用集合类型作为列表控件的ItemsSource时一般会考虑用ObserableCollection
代替List
,因为其实现了INotifyCollectionChanged和INotifyPropertyChanged接口能把集合的变化立刻显出来。3、使用ADO.NET做为Binding的源一般是DataTable dt=Bussiness.GetData();listBox1.ItemsSource=dt.DefaultView;这里的DefaultView是个DataView类型的对象。DataView实现了IEnumerable接口,所以可以给ItemsSource赋值。DataTable不能直接拿来为ItemsSource赋值但是可以将DataTable对象放到一个对象的DataContext属性里,并把ItemsSource与一个既没有Path有没有Source的Binding关联起来,Binding能自动找到DefaultView并当做自己的Source代码:DataTable dt=this.Load();this.listViewStudents.DataContext=dt;this.listViewStudents.SetBinding(ListView.ItemsSourceProperty,new Binding());GridView可以为GridViewColumn设置HeaderTemplate和CellTemplate,他们的类型都是DataTemplate。4、使用Xml数据作为Binding源迄今为止 .net framework提供了2套处理xml数据的类库1、符合DOM标准的类库:包括XmlDocument、XmlElement、XmlNode、XmlAttribute2、Linq:包括XDocument、XElement、XNode、XAttribute注意:当使用Xml作为Binding的Source时,这里讲使用XPath,而非PathXPath=@Id 这里使用@符号表示的是XML元素的Attribute把XML数据和XmlDataProvider对象直接写在XAML代码里,那么XML数据要放在
...
中。代码中用到HierarchicalDataTemplate代码如下:
10、使用Linq作为Binding的源Linq的查询结果是个IEnumberable
类型的对象可以作为列表控件的ItemsSource来使用9、使用ObjectDataProvider作为Binding的Source把对象作为数据源提供给BindingObjectDataProvider作用是用来包装一个以方法暴露数据的对象代码:ObjectDataProvider odp = new ObjectDataProvider(); odp.ObjectInstance = new Calculator(); odp.MethodName = "Add"; odp.MethodParameters.Add("0"); odp.MethodParameters.Add("0"); Binding bindingToArg1 = new Binding("MethodParameters[0]") { Source = odp, //告诉Binding只负责把从UI元素收集到的数据写入Source(ObjectDataProvider对象) BindsDirectlyToSource=true, //一有更新立即传回Source UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged }; this.txtNum1.SetBinding(TextBox.TextProperty, bindingToArg1); txtNum2.SetBinding(TextBox.TextProperty, new Binding("MethodParameters[1]") { Source = odp, BindsDirectlyToSource = true, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); txtResult.SetBinding(TextBox.TextProperty, new Binding(".") { Source = odp });8、使用Binding的RelativeSource略 Binding对数据的转换与校验Binding在Target与Source之间起着桥梁的作用,但是桥上也有关卡,用来 数据转换盒数据校验数据校验:Binding的ValidationRules属性继承抽象类:ValidationRule,重写override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)该方法数据转换:Binding的Converter属性实现IValueConverter接口public infterface IValueConverter{ //当数据从Binding的Source流向Target时Converter被调用 /** *参数1:未转型之前的值 *参数2:确定方法的返回类型,outputType *参数3:把额外的信息传入方法 *另外Binding的Model属性会影响这2个方法的调用 */ object Converter(object value,Type targetType,object parameter,CultureInfo culture); //当数据从Binding的Target流向Source时ConverterBack被调用 object ConvertBack(object value,Type targetType,object parameter,CultureInfo culture);}MultiBinding与Binding一样都是以BindingBase为基类其有个属性Bindings类型为Collection
例如,注册用户时有重复输入用户名或密码,来控制提交按钮的启用与禁用Converter:class LogonMultiBindingConverter:IMultiValueConverter //实现的是IMultiBindingConverter接口 { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { //throw new NotImplementedException(); if (!values.Cast
().Any(text=>string.IsNullOrEmpty(text))&& values[0].ToString()==values[1].ToString()&& values[2].ToString()==values[3].ToString() ) { return true; } return false; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }后台代码: Binding b1 = new Binding("Text") { Source=txt1 }; Binding b2 = new Binding("Text") { Source = txt2 }; Binding b3 = new Binding("Text") { Source = txt3 }; Binding b4 = new Binding("Text") { Source = txt4 }; MultiBinding bindings = new MultiBinding() { Mode=BindingMode.OneWay}; //MultiBinding对添加子级Binding的顺序是敏感的 bindings.Bindings.Add(b1); bindings.Bindings.Add(b2); bindings.Bindings.Add(b3); bindings.Bindings.Add(b4); bindings.Converter = new LogonMultiBindingConverter(); btnSubmit.SetBinding(Button.IsEnabledProperty, bindings);

 

转载于:https://www.cnblogs.com/hailiang2013/archive/2013/04/22/3035348.html

你可能感兴趣的文章
一声祝贺,几句致歉和我的话
查看>>
【网上转载搜罗】本博客花里胡哨(划掉)效果js代码
查看>>
win7 能ping通dns, 但无法解析域名
查看>>
centos 软件安装包下载网站
查看>>
nmap 端口扫描工具
查看>>
Excel vlookup筛选两列的重复项
查看>>
CentOS7 SSH免密码登录
查看>>
配置了BFD MAD, 在IRF正常情况下的 BFD状态是不是 down?
查看>>
SQL server 2012定期的备份数据库--完整+差异+事物
查看>>
C语言 - 可变参数再stm32中的应用
查看>>
vscode + platformIO开发stm32f4
查看>>
最新SSM框架整合2019
查看>>
LinkedList的线程安全解决办法
查看>>
eclipse调整控制台长度
查看>>
jsonp和ajax
查看>>
EAS 之F7控件实现多选择并保存
查看>>
S-HR之用户行政范围查询
查看>>
eas之动态调用Ui界面,并在UI之间传递变量
查看>>
开源协议许可
查看>>
S-HR之导入模板指向实现类配置
查看>>