自学WPF之Binding(一)
Binding的重要性就不作介绍了,是作为数据交互的支撑,下面来介绍一下为Binding指定源(Source)的几种方法:
- 把普通CLR类型的单个对象指定为Source:包括.NET Framework自带类型的对象和用户自定义类型的对象。如果类型继承了INotifyPropertyChanged的接口,则可以通过在属性的set激发PropertyChanged事件来通知绑定数据已经更新。
- 把普通CLR集合类型对象指定为Source:包括数组。List<T>、ObservableCollection<T>等集合类型。实际工作中,我们常把一个集合作为ItemsControl的派生类的数据源来使用,一般把控件的ItemsSource属性使用binding关联到一个集合对象上。
- 把ADO.NET数据对象指定为Source:包括DataTable、DataView等对象。
- 使用XMLDataProvider把XML数据指定为Source:用于级联式控件绑定数据源,如TreeView、menu等,Binding关联到树状结构的Xml上。
- 把依赖对象(Dependence Object)指定为Source:依赖对象不仅可以作为Binding的目标,同时也可以作为Binding的源。依赖对象的属性可以作为Binding的path。
- 把容器的DataContext 指定为Source:先建立一个Binding,只给它设置path而不设置Source,这时候Binding会自动把控件的DataContext当作自己的Source(它会沿着控件树一层一层往外找直到找到带有path制定属性的对象为止)。
- 通过ElementName指定Source:在C#里可以直接把对象赋值给Binding,但Xaml无法访问对象,只能用NAME属性,来找到对象。
- 通过Binding的RelativeSource属性相对的指定Source:当空间需要关注自己的、自己容器的、或者自己内部元素的某个值就需要使用这种方法。
- 把ObjectDataProvider对象指定为Source:当数据源的数据不是通过属性而是通过方法暴漏给外界的时候,我们可以使用这两种对象来包装数据源再把他们作为指定的Source。
- 把使用LINQ检索的得到的数据作为Binding对象。
下面我们来介绍每一种情况。
(1)继承了INotifyPropertyChanged的接口:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace MyFirstWPFTest { public class Employee:INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private int _id; public int Id { get { return _id; } set { _id = value; } } private string _name; public string Name { get { return _name; } set { _name = value; if (this.PropertyChanged != null) { this.PropertyChanged.Invoke(this,new PropertyChangedEventArgs("Name")); } } } private int _age; public int Age { get { return _age; } set { _age = value; } } } }
前台设计代码:
<Window x:Class="MyFirstWPFTest.BindingPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="BindingPage" Height="300" Width="300"> <StackPanel> <TextBox Name="txtName" BorderBrush="Black" Margin="5"></TextBox> <Grid > <Grid.ColumnDefinitions> <ColumnDefinition> </ColumnDefinition> <ColumnDefinition> </ColumnDefinition> </Grid.ColumnDefinitions> <Button Content="Cancel" Grid.Column="0" Height="23" Name="Cancel" Click="Cancel_Click" Width="75" /> <Button x:Name="btnOK" Grid.Column="1" Width="78" Click="btnOK_Click">Add Age</Button> </Grid> </StackPanel> </Window>
后台逻辑代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace MyFirstWPFTest { /// <summary> /// BindingPage.xaml 的交互逻辑 /// </summary> public partial class BindingPage : Window { Employee em; public BindingPage() { InitializeComponent(); //em = new Employee(); //Binding binding = new Binding(); //binding.Source = em; //binding.Path = new PropertyPath("Name"); //BindingOperations.SetBinding(this.txtName, TextBox.TextProperty, binding); this.txtName.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = em = new Employee() }); } private void btnOK_Click(object sender, RoutedEventArgs e) { em.Name += "lily"; } private void Cancel_Click(object sender, RoutedEventArgs e) { this.txtName.Text = ""; } } }
运行效果:
同样绑定也可以在前台实现:
<TextBox Name="txtbind" Text="{Binding Path=Value,ElementName=silder1}" BorderBrush="Black" Margin="5"/> <Slider Name="silder1" Maximum="100" Minimum="0" Margin="5"/>
运行效果:
这里需要说明一下,如果在文本框里输入数字,当光标离开文本框时,silder会随之变化,之所以在losefocus后变化是因为UpdateSourceTrigger属性的值,当需要输入值以后就随之变化的话,需将UpdateSourceTrigger属性值设置为PropertyChanged。