WPF Binding(绑定)详解
Binding概念理解:
WPF为了实现了UI与数据逻辑的解耦,将UI从数据逻辑中分离出来形成Xaml文件,而UI与数据逻辑之间的联系则通过Bingding来实现。Bingding就像UI与数据逻辑之间的桥梁,能够让分离的两部分组合成一个整体,实现WPF的数据驱动。
把Binding比作桥梁,那么它的两端分别是Binding的源(Source)和目标(Target),Path为Binding指定访问路径,数据从哪里来哪里就是源(未指明Source,数据就会一直往上查找),Bingding是驾在中间的桥梁,Bingding的目标是数据去向哪里。当Bingding的源变化需要通知目标变化时,需要通过属性的set语句激发一个ProtertyChanged事件。这个事件不需要我们自己声明,而是让数据源类实现System.ComponentModel名称空间中的INotifyPropertyChanged接口。
Binding数据流向的属性是Mode:TwoWay(双向)、OneWay(单向)、OneTime(单次)、OneWayToSource(对数据源单向)和Default(根据具体目标情况确定,如可编辑未双向模式)。数据源根据什么类型变化进行通知,可设置属性UpdateSourceTrigger:PropertyChanged、LostFocus、Explicit(显式,在程序启动时更新源)和Default。
实例链接:WPF Binding(绑定)详解实例
WPF前端数据绑定:
实例如下:拖动Slider滑块值时,绑定Slider.Value的TextBox.Text跟着变化。
<Grid><StackPanel><TextBox Text="{Binding Path=Value,ElementName=slider1}"/><Slider x:Name="slider1" Maximum="100" Minimum="0"/></StackPanel> </Grid>
WPF后端数据绑定:
实例如下:一个TextBox.Text绑定到另一个TextBox.Text,另一个TextBox.Text变化时它也跟着变化。
<TextBox x:Name="tbSource" BorderBrush="Black" Margin="5"/>
<TextBox x:Name="tbPath" BorderBrush="Black" Margin="5"/>
//1.创建Bingding
Binding binding = new Binding()
{Source = tbSource, // 数据源 Path = new PropertyPath("Text"), // 需绑定的数据源属性名 Mode = BindingMode.TwoWay, // 绑定模式 UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //触发器
};//2.设置Bingding
//方法1
//tbPath.SetBinding(TextBox.TextProperty, binding);//方法2
BindingOperations.SetBinding(tbPath // 需绑定的控件 ,TextBox.TextProperty // 需绑定的控件属性 ,binding);
Binding不同使用方式和场景:
Binding还支持多级路径。如,我们想让一个TextBox显示另一个TextBox的长度,可以这样写:
<StackPanel Margin="10"><TextBox x:Name="textBox1" BorderBrush="Black" Margin="5"/><TextBox x:Name="textBox2" Text="{Binding Path=Text.Length,ElementName=textBox1,Mode=OneWay}" BorderBrush="Black" Margin="5"/>
</StackPanel>
集合类型的索引器(Indexer)又称为带参数属性,所有索引器也能作为Path来使用。
<TextBox x:Name="txt1" BorderBrush="Black" Margin="5"/>
<TextBox x:Name="txt2" Text="{Binding Path=Text.[3],ElementName=txt1,Mode=OneWay}" BorderBrush="Black" Margin="5"/>
当数据源本身就是数据就不需要使用Path指明,Path后面可以.来表示,也可以之间省略Path。
<Window x:Class="WpfBingdingDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfBingdingDemo"xmlns:sys="clr-namespace:System;assembly=mscorlib"mc:Ignorable="d"Title="MainWindow" Height="300" Width="400"><Window.Resources><sys:String x:Key="myStr">Hello World!</sys:String></Window.Resources><Grid><StackPanel><TextBox x:Name="txt1" BorderBrush="Black" Text="{Binding Source={StaticResource ResourceKey=myStr},Mode=OneWay}" Margin="5"/><TextBox x:Name="txt2" Text="{Binding Path=Text.[3],ElementName=txt1,Mode=OneWay}" BorderBrush="Black" Margin="5"/></StackPanel></Grid>
</Window>
当数据源是集合时,可以通过"/"来表示。当结合元素的属性仍然时集合时,我们想不子级集合中的元素当作Path,则可以使用多级斜线的语法(如:"/Provinces/CityList.Name")。
当没有指定数据源时,Binding会沿着UI元素树一路向上找,每到一个结点就要看看这个结点的DataContext是否具有Path所指定的属性。如果有,那就把这个对象作为自己的Source。
//后台定义类public class Student{public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }}<StackPanel><StackPanel.DataContext><local:Student Id="3" Name="Tom" Age="12"/></StackPanel.DataContext><!--未指明Source,Binding往上查找--><TextBox Text="{Binding Name}" BorderBrush="Black" Margin="5"/></StackPanel>
使用XML数据作为Binding源:
.Net Framework提供了两套处理XML数据的类库:符合DOM标准类库,以LINQ为基础的类库。大多数据传输基于SOAP(简单对象访问协议),而SOAP又是通过将对象序列化为XML文本进行传输。XML文本是树形结构,它能方便地用于线性结合和树形结构数据。使用XPath指明Binding XML路径,路径后使用@符号加字符串表示的是XML元素的Attribute,不加@的字符串表示的是子级元素。
DOM标准的XML类库:
<StackPanel Grid.Row="2" Margin="50"><StackPanel.Resources><XmlDataProvider x:Key="MyColors" Source="E:\Xml\Colors.xml" XPath="colors"/></StackPanel.Resources><ListBox x:Name="listBox1" Height="128" Width="92" ItemsSource="{Binding Source={StaticResource MyColors}, XPath=color/@name,Mode=TwoWay}"/><TextBox x:Name="textBox1" Height="28" Width="92" TextWrapping="Wrap" Text="{Binding SelectedValue, ElementName=listBox1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
LINQ查询的结果是IEnumerable<T>类型对象,而IEnumerable<T>派生自IEnumerable,所有它可以作为ItemsSource来使用。
XDocument xdoc = XDocument.Load(@"E:\Xml\colors.xml");
listBox2.ItemsSource = from element in xdoc.Descendants("color") where element.Attribute("name").Value.StartsWith("b")select new{Name=element.Attribute("name").Value,ID= element.Attribute("ID").Value};
listBox2.DisplayMemberPath = "Name";
使用ObectDataProvider对象作为Binding的Source:
在我们开发过程中,很难保证一个类所有数据都使用属性暴露出来,这个时候需要使用ObjectDataProvider来包装作为Binding源的数据对象。
实例:通过ObjectDataProvider传递对类方法并作为数据源。
public class Student{public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }public Student GetStudent(){return new Student{Id = 2,Name = "Jack",Age = 9};}}<Grid><Grid.Resources><ObjectDataProvider x:Key="student" ObjectType="{x:Type local:Student}" MethodName="GetStudent" /></Grid.Resources><TextBlock Text="{Binding Name,Source={StaticResource student}}" FontSize="30" VerticalAlignment="Center" HorizontalAlignment="Center"/></Grid>
使用Binding的RelativeSource属性进行绑定:
当我们不确定作为Source的对象叫什么名字,但知道它与作为Binding目标的对象在UI布局上有相对关系,比如控件自己关联自己的某个数据、关联自己某级容器的数据。这个时候我们就要使用Binding的RelativeSource属性。
实例:TextBox.Text绑定它上面布局元素的Name。
<Grid x:Name="grid1"><Grid Width="100" Height="100" x:Name="grid2"><Border Width="60" Height="60"><TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid},AncestorLevel=2},Path=Name}"/></Border></Grid></Grid>
Binding对数据的转换和校验:
我们可以在连接Source和Target之间Binding桥上设置关卡,来判断哪些符号条件的数据流通。通过实现ValidationRule这个抽象类,对数进行校验。
实例:TextBox.Text与Slider.Value数值进行绑定,并对输入TextBox值进行校验,校验不通过则提示。
<StackPanel><TextBox x:Name="textBox1" Margin="5"/><Slider x:Name="slider1" Minimum="0" Maximum="100" Margin="5"/></StackPanel>
public class RangeValidationRule : ValidationRule{public override ValidationResult Validate(object value, CultureInfo cultureInfo){double d = 0;if(double.TryParse(value.ToString(),out d)){if(d>=0&&d<=100){return new ValidationResult(true, null);}}return new ValidationResult(false, "Validation Failed");}}public partial class ValidationRuleDemo : Window{public ValidationRuleDemo(){InitializeComponent();Binding binding = new Binding("Value") { Source = this.slider1 };binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;RangeValidationRule rule = new RangeValidationRule();binding.ValidationRules.Add(rule);//当数据校验失败时Binding会发出一个信号并以Binding对象的Target为起点在UI元素树上传播。binding.NotifyOnValidationError = true;this.textBox1.SetBinding(TextBox.TextProperty, binding);this.textBox1.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.ValidationError));}private void ValidationError(object sender, RoutedEventArgs e){this.textBox1.ToolTip = Validation.GetErrors(this.textBox1)[0].ErrorContent.ToString();}}
Binding的数据转换(Converter):
我们在进行数据绑定时,Source和Target传递数据类型可能不一致,这个时候我们就可以用Converter进行数据转换。
实例:TextBox前景色绑定到自身输入的Text,并通过Converter进行类型转换。
<Grid><TextBox Width="200" Height="30" FontSize="20" FontWeight="Bold" Foreground="{Binding RelativeSource={RelativeSource self},Path=Text,Mode=TwoWay, Converter={StaticResource ct}}"/></Grid>
public class BrushConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){string color = System.Convert.ToString(value).ToLower();switch(color){case "red":return new SolidColorBrush((Color)ColorConverter.ConvertFromString(color));case "green":return new SolidColorBrush((Color)ColorConverter.ConvertFromString(color));case "blue":return new SolidColorBrush((Color)ColorConverter.ConvertFromString(color));}return new SolidColorBrush(Colors.Black);}//双向转换回调public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){var solidColorBrush = (SolidColorBrush)value;if(solidColorBrush!=null){return "Red";}return "Black";}}
多路绑定(MultiBinding):
实例:当多个TextBox输入字符一致时,Button的IsEnable属性为true,否Button不能点击。
<StackPanel><TextBox x:Name="txt1" Height="30" Margin="5"/><TextBox x:Name="txt2" Height="30" Margin="5"/><TextBox x:Name="txt3" Height="30" Margin="5"/><Button x:Name="btn1" Content="Click" Width="100" Height="30" Margin="5"/></StackPanel>
public partial class MultiBindingDemo : Window{public MultiBindingDemo(){InitializeComponent();SetMultiBinding();}private void SetMultiBinding(){Binding b1 = new Binding("Text") { Source = this.txt1 };Binding b2 = new Binding("Text") { Source = this.txt2 };Binding b3 = new Binding("Text") { Source = this.txt3 };MultiBinding mb = new MultiBinding() { Mode = BindingMode.OneWay };mb.Bindings.Add(b1);mb.Bindings.Add(b2);mb.Bindings.Add(b3);mb.Converter = new MultiBindingConverter();this.btn1.SetBinding(Button.IsEnabledProperty, mb);}}public class MultiBindingConverter : IMultiValueConverter{public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture){if(!values.Cast<string>().Any(text=>string.IsNullOrEmpty(text))&&values[0].ToString()==values[1].ToString() && values[0].ToString() == values[2].ToString()){return true;}return false;}public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture){throw new NotImplementedException();}}
实例链接:WPF Binding(绑定)详解实例
WPF Binding(绑定)详解相关推荐
- GTalk服务绑定详解
我们都知道GTalk是一个非常好的即时通讯,这里不多介绍,本文主要介绍GTalk服务绑定. 为了使用GTalk服务,你需要使用bindService将其绑定到应用程序组件上. bindServi ...
- 子域名绑定html,DEDE二级域名(多站点)绑定详解
关键字描述:详解 站点 栏目 顶级   设置 绑定 目录 支持 二级域名 首先,DEDE在绑定多域名之前,需先作如下准备: 1.服务器或空间支持, 2.将你的域名指定到目录 接着我们就 ...
- WPF WinAPI 编程详解(四 实例 )
QQ/微信定时发送消息 1--检测QQ/微信窗口 今天先来说说第一步:怎样检测QQ和微信窗口. 1,思路:首先获取QQ和微信的进程ID,中间要注意两个注意点 <1>请保证要群发的QQ/微信 ...
- emacs按键绑定详解
key-binding: https://crazylxr.github.io/spacemacas-zh_CH-doc/binding-keys.html 概述:Emacs的键绑定方式看起来花样繁多 ...
- WCF系列学习笔记4之绑定详解
标准绑定 绑定的基本概念:通道模型具有极大的灵活性,可以在协议通道,编码器,传输通道等各个方面进行设置,每次都需要设置一个完整的通道栈是一个较为复杂的事情,从传输协议上看,有HTTP,TCP,UDP, ...
- WPF入门教程详解1——label、TextBlock、Button、Border、RadioButton、CheckBox、 数据绑定、案例、ToolTip、GroupBox、Expand、Fram
视频地址:https://www.bilibili.com/video/BV1iY411w7zD/?p=3&spm_id_from=pageDriver&vd_source=5dc01 ...
- Android databinding之数据单向与双向绑定详解与使用(三)
一.介绍 通过前面两篇文档,我们大概了解了databinding的工作方式,view的初始化,recycleview的使用.但是这些UI都离不开数据的填充,数据的修饰. 在说到数据绑定,好多开发者平时 ...
- 空WPF项目元素详解 by:凉游浅笔深画眉 / Net7Cracker
我们在VisualStudio2010创建了一个空WPF程序,现在我们来对这个空WPF程序的所有元素进行讲解! 1.<Window x:Class="WpfApplication1.M ...
- js 中的this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解
壹 ❀ 引 工具猴-免费在线工具-在线工具箱- 可以说this与闭包.原型链一样,属于JavaScript开发中老生常谈的问题了,百度一搜,this相关的文章铺天盖地.可开发好几年,被几道this题安 ...
最新文章
- 使用datatables 中文排序
- 电脑模拟器哪个好_《英雄聯盟:激鬥峽谷》电脑版哪个安卓模拟器好用?《英雄聯盟:激鬥峽谷》手游电脑版怎么玩...
- 自定义myeclipse中的servlet模板文件
- 整数奇偶排序(信息学奥赛一本通-T1181)
- 【C++】重载赋值运算符
- sci写作sci写作模板_有写作错误吗? bibisco简介
- 基于Ogre的DeferredShading(延迟渲染)的实现以及应用
- memcached简单的使用教程
- 华为 常用的查看命令
- WordPress如何在后台显示自带友情链接?
- 传奇地图时间限制脚本_脚本第一课限制进入次数地图设置方法
- 360全景拍摄用鱼眼镜头还是广角镜头?有什么区别?
- 创建系统映像时包含了 D、E 盘
- 使用python裁剪mp3
- (已更新)全新商城微信小程序源码支持对接公众号
- 山西大同大学计算机科学与技术在哪个校区,山西大同大学有几个校区及校区地址 哪...
- 用友u813.0服务器系统,用友U8+ 13.0 登录操作卡顿
- Linux下安装jdk
- php7.0 freetype_php 添加 freetype支持
- unity消消乐源码