WPF数据绑定Binding(二)
WPF数据绑定Binding(二)
1.UI控件直接的数据绑定
UI对象间的绑定,也是最基本的形式,通常是将源对象Source的某个属性值绑定 (拷贝) 到目标对象Destination的某个属性上。源属性可以是任意类型,但目标属性必须是依赖属性(Dependency Property)。通常情况下我们对于UI对象间的绑定源属性和目标属性都是依赖属性 (有些属性不是) ,因为依赖属性有垂直的内嵌变更通知机制,WPF可以保持目标属性和源属性的同步。
布局文件绑定源码:
<StackPanel Orientation="Vertical"> <Slider Name="slider1" Margin="10 10 10 0" Minimum="9" Maximum="50" Value="12" TickFrequency="5"></Slider> <TextBlock Name="txtB_info" Text="上海世博会" Margin="10 10 10 0" FontSize="{Binding ElementName=slider1, Path=Value}"></TextBlock> <TextBox Name="txt_fontSize" Text="{Binding ElementName=slider1, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="10 10 10 0"></TextBox> <TextBox Margin="10 10 10 0"></TextBox> </StackPanel>
1.1 C#后台源码进行数据绑定源码:
1. 调用FrameworkElement 或FrameworkContentElement对象的SetBinding方法
2. 调用BindingOperations.SetBinding静态方法
//绑定对象 Binding binding = new Binding(); //设置绑定数据源对象 binding.ElementName = "slider1"; //设置数据流的方向 binding.Mode = BindingMode.TwoWay; //设置源属性 binding.Path = new PropertyPath("Value"); //进行数据绑定 txtB_info.SetBinding(TextBlock.FontSizeProperty, binding); //第二中绑定方式 BindingOperations.SetBinding(txt_fontSize, TextBox.TextProperty, binding);
1.2 C#后台清除绑定的数据
当你在应用程序中某个地方添加了绑定,而在某个时候又不想这个绑定在接下来继续有效时,你可以有两种方式来断开这个绑定:
1. 用BindingOperations.ClearBinding静态方法。
例如BindingOperations.ClearBinding(currentTextBlock, TextBlock.TextProperty); BindingOperations同时还提供了ClearAllBindings方法,只需要传入要清除绑定的目标对象的名称,它就会将所有这个对象的绑定移除。
2.简单的将目标属性设置为一个新的值。
这个简单的方法同样有效,可以断开与前边设置的binding的连接。简单的设置为任何值即可:如:currentTextBlock.Text = “it’s a new value.”;
//清除txtB_info的数据绑定 绑定数据流向 如果为Mode=TwoWay 侧不能清除绑定 //只要Mode的值不是TwoWay txtB_info.FontSize = 15; //最好使用下面的方式清除数据绑定 BindingOperations.ClearBinding(txt_fontSize, TextBox.TextProperty); //清除所有绑定 BindingOperations.ClearAllBindings(txt_fontSize);
效果图:
1.3 Binding对象的属性说明
序号 属性名 描述
1 Converter 转换器,将绑定的内容转换成自己需要的内容。自定义转换类 必须继承于:IValueConverter接口
2 ElementName 绑定的源对象,本人理解 专程用于UI控件之间属性的绑定
3 FallbackValue 绑定无法返回有效值时的默认显示值
4 Mode 绑定方式,枚举类型 Default OneWay TwoWay OneTime OneWayToSource
5 Path 属性 路径,用来指定要绑定数据源的路径,其性质是一个属性,该属性该当是依靠属性,
也即便能够告终积极更新机制的【单个类实现INotifyPropertyChanged、集合要 实现INotifyCollectionChanged接口】
6 RelativeSource 常用于自身绑定或者数据模板中来指定绑定的源对象及控件模块中的绑定。
7 Source 源对象,控件或自定义对象等。
8 StringFormat 格式化表达式
9 UpdateSourceTrigger 在双向绑定时TwoWay 或 OneWayToSource 时。用来确定属性更改的时机。
UpdateSourceTrigger枚举类型:Default,PropertyChanged,LostFocus,Explicit。
10 ValidationRules 验证规则.可以被设置为一个或多个派生自ValidationRule的对象,
每个规则都会检查特定的条件并更具结果来标记数据的有效性
1.4 Mode 五种绑定方式 Default OneWay TwoWay OneTime OneWayToSource
1. Default 默认的,一般来说,对于用户可以设置的(如TextBox.Text属性)是双向的,而其他则是单向的。
2. OneWay 单向绑定 当源属性变化时更新目标属性。
3. TwoWay 双向绑定 数据源和目标都会随之改变,但是更加消耗系统资源。
4. OneTime 只绑定一次,以后数据源的改变都不会改变目标属性值。(如果用C#代码后台调用:
BindingExpression bindingExpression = BindingOperations.GetBindingExpression(txtB_info, TextBlock.FontSizeProperty);//方式二
//BindingExpression bindingExpression=txtB_info.GetBindingExpression(TextBlock.FontSizeProperty);//方式二
bindingExpression.UpdateSource();)
5. OneWayToSource 反向绑定,目标属性的改变 及时更新数据源。
1.5 UpdateSourceTrigger 四种用来确定属性更改的时机,对于 Model=TwoWay 及 OneWayToSource是源数据改变时机。
1.Default 由不同控件控制. 例如 TextBox, 当 LostFocus 事件触发时,目标绑定发生变化.
2.PropertyChanged 意味着当目标控件值发生变化时,源数据立马更新.例如, TextBox是目标绑定,当输入字符时, 源数据也发生变化.
这就意味着当你输入字符的时候,TextBox的数据Text也在改变 源数据也在改变。 这是比较消耗系统资源,更新的频率比较快。
3.LostFocus 当目标控件失去焦点后,源数据发生变化。
4.Explicit 当UpdateSourceTrigger 设置为 Explicit, 数据源不会自动更新,只有在后代码里面显示的触发。
BindingExpression bindingExpression = BindingOperations.GetBindingExpression(txtB_info, TextBlock.FontSizeProperty);//方式一
//BindingExpression bindingExpression=txtB_info.GetBindingExpression(TextBlock.FontSizeProperty);//方式二
bindingExpression.UpdateSource();
2.UI属性绑定数据对象。
2.1 UI属性直接绑定实例对象 2.2 UI属性直接绑定静态对象 2.3 UI属性绑定资源中的对象。
前台布局代码
<Window x:Class="WPFBindingDemo.RelativeSourceWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WPFBindingDemo" Title="RelativeSourceWindow" Height="300" Width="500"> <Window.Resources> <local:Student x:Key="stuKey" StudentID="20110702" Name="王六" EntryDate="2011-09-01" Credit="80.5"/> </Window.Resources> <StackPanel Orientation="Vertical"> <GroupBox Header="绑定实例对象"> <StackPanel Orientation="Horizontal" Name="stackPanel1"> <TextBlock Text="学号:"/> <TextBlock Text="{Binding Path=StudentID}"/> <TextBlock Text="姓名:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="入学日期:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=EntryDate, StringFormat=yyyy-MM-dd}"/> <TextBlock Text="学分:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Credit}"/> </StackPanel> </GroupBox> <GroupBox Header="绑定静态对象"> <StackPanel Orientation="Horizontal" DataContext="{x:Static local:GlobalData.student}"> <TextBlock Text="学号:"/> <TextBlock Text="{Binding Path=StudentID}"/> <TextBlock Text="姓名:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="入学日期:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=EntryDate, StringFormat=yyyy-MM-dd}"/> <TextBlock Text="学分:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Credit}"/> </StackPanel> </GroupBox> <GroupBox Header="绑定资源中的对象"> <StackPanel Orientation="Horizontal" DataContext="{StaticResource ResourceKey=stuKey}"> <TextBlock Text="学号:"/> <TextBlock Text="{Binding Path=StudentID}"/> <TextBlock Text="姓名:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="入学日期:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=EntryDate, StringFormat=yyyy-MM-dd}"/> <TextBlock Text="学分:" Margin="20 0 0 0"/> <TextBlock Text="{Binding Path=Credit}"/> </StackPanel> </GroupBox> <GroupBox Header="修改绑定对象的值"> <StackPanel Orientation="Horizontal" ButtonBase.Click="StackPanel_Click"> <Button Name="btn_new" Content="修改实体对象值" Margin="10 0 0 0"></Button> <Button Name="btn_static" Content="修改静态对象值" Margin="20 0 0 0"></Button> <Button Name="btn_resource" Content="修改资源中对象的值" Margin="20 0 0 0"></Button> </StackPanel> </GroupBox> </StackPanel> </Window>
辅助 Student类
public class Student { public Student() { } private int studentID; /// <summary> /// 学号 /// </summary> public int StudentID { get { return studentID; } set { studentID = value; } } private string name; /// <summary> /// 姓名 /// </summary> public string Name { get { return name; } set { name = value; } } private DateTime entryDate; /// <summary> /// 入学日期 /// </summary> public DateTime EntryDate { get { return entryDate; } set { entryDate = value; } } private double credit; /// <summary> /// 学分 /// </summary> public double Credit { get { return credit; } set { credit = value; } } }
Xaml 后台代码:
public RelativeSourceWindow() { //对静态对象进行赋值 Student stu = new Student { StudentID = 20130602, Name = "李四", EntryDate = DateTime.Parse("2012-09-15"), Credit = 40.5 }; GlobalData.student = stu; InitializeComponent(); //实例对象数据源 stackPanel1.DataContext = new Student() { StudentID=20130501, Name="张三", EntryDate=DateTime.Parse("2013-09-01"), Credit=0.0}; } private void StackPanel_Click(object sender, RoutedEventArgs e) { Button btn = e.OriginalSource as Button; if (btn != null) { switch (btn.Name) { case "btn_new": { Student stu = (Student)stackPanel1.DataContext; stu.Name = "张三三"; stu.Credit = 34.5; } break; case "btn_static": { GlobalData.student.Name = "李四四"; GlobalData.student.EntryDate = DateTime.Now; } break; case "btn_resource": { Student stu = (Student)this.FindResource("stuKey"); stu.Name = "王六六"; stu.StudentID = 20140025; } break; default: break; } } }
全局静态变量:
public class GlobalData { public static Student student = null; }
效果截图:
2.4 实现
积极更新机制的【单个类实现INotifyPropertyChanged、集合要 实现INotifyCollectionChanged接口】 Student 要实现 INotifyPropertyChanged 接口。
修改后 Student 类
public class Student:INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = this.PropertyChanged; if (handler != null) { PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName); handler(this, e); } } public Student() { } private int studentID; /// <summary> /// 学号 /// </summary> public int StudentID { get { return studentID; } set { if (studentID == value) return; studentID = value; OnPropertyChanged("StudentID"); } } private string name; /// <summary> /// 姓名 /// </summary> public string Name { get { return name; } set { if (name == value) { return; } name = value; OnPropertyChanged("Name"); } } private DateTime entryDate; /// <summary> /// 入学日期 /// </summary> public DateTime EntryDate { get { return entryDate; } set { if (entryDate == value) return; entryDate = value; OnPropertyChanged("EntryDate"); } } private double credit; /// <summary> /// 学分 /// </summary> public double Credit { get { return credit; } set { if (credit == value) return; credit = value; OnPropertyChanged("Credit"); } } }
本文写到这里,希望阅读后对你有帮助。本人菜鸟一个,望提出宝贵意见。