您的位置:首页 > 其它

Binding基础 文摘

2017-04-03 15:16 169 查看

简要

Binding基础

Binding源与路径

列举Binding的源

Binding基础

从Coding中看Binding的基础。

先定义一个Student类:

publicclassStudent:INotifyPropertyChanged

{

publiceventPropertyChangedEventHandlerPropertyChanged;


privatestringname;

publicstringName

{

get

{

returnthis.name;

}

set

{

name=value;

if(PropertyChanged!=null)

{

this.PropertyChanged.Invoke(this,newPropertyChangedEventArgs("Name"));

}

}

}

}
XAML设计:

<StackPanelHeight="70">

<TextBoxx:Name="textBoxName"BorderBrush="Black"Margin="5"></TextBox>

<ButtonContent="AddName"Margin="5"Click="Button_Click"></Button>

</StackPanel>
后台部分:

publicpartialclassMainWindow:Window

{

Studentstu;


publicMainWindow()

{

InitializeComponent();

stu=newStudent();

Bindingbinding=newBinding();

binding.Source=stu;

binding.Path=newPropertyPath("Name");


BindingOperations.SetBinding(this.textBoxName,TextBox.TextProperty,binding);

}


privatevoidButton_Click(objectsender,RoutedEventArgse)

{

stu.Name+="LiLin";

}

}




在这个例子中,binding的源是stu,binding的路径是Name,既UI关心的那个属性。

首先,定义的Student实现了INotifyPropertyChanged接口,并在Name的set中激发PropertyChanged事件,这是为了是Binding机制能自动监听,并会通知Binding目标端的UI现实新的值。

在后台代码中,Binding部分是先声明Binding类型变量并创建实例,然后指定源与路径,最后使用BindingOperations.SetBinding(…)来实现数据源与目标的连接。

实际中,不需要这么麻烦地实现Binding,因为TextBox继承自FrameworkElement,对BindingOperations.SetBinding(…)进行了封装,提供SetBinding方法:

publicBindingExpressionBaseSetBinding(DependencyPropertydp,BindingBasebinding)

{

returnBindingOperations.SetBinding(this,dp,binding);

}
使用SetBinding可以简化为:

InitializeComponent();

stu=newStudent();

this.textBoxName.SetBinding(TextBox.TextProperty,newBinding("Name"){Source=stu});

Binding的源与路径

Binding的源只要是一个对象,且拥有公开的属性。可以是实现了INotifyPropertyChanged接口的自定义类、控件、集合、XML…

把控件作为Binding的源:

<StackPanelHeight="70">

<TextBoxx:Name="textBoxValue"BorderBrush="Black"Margin="5"Text="{BindingPath=Value,ElementName=slider,UpdateSourceTrigger=PropertyChanged}"></TextBox>

<Sliderx:Name="slider"Maximum="100"Minimum="0"Margin="5"></Slider>

</StackPanel>




控制Binding的方向和数据更新触发方式:

控制Binding数据流向的属性是Mode,枚举。可以取值为:TwoWay、OneWay、OnTime、OneWayToSource、Default。

控制数据更新触发方式的属性是UpdateSourceTrigger,类型是UpdateSourceTrigger枚举,可以取值为:PropertyChanged、LostFocus、Explicit和Default。

Binding的路径:

Binding的路径是指示Binding关注的属性。

为Binding指定源的几种方法:

把普通的CLR类型单一对象指定为Source:该类型需实现INotifyPropertyChanged接口,并通过属性的Set语句里激发PropertyChanged事件;

把普通的CLR集合类型对象指定为源:包含数组、List<T>、ObservableCollection<T>等集合类型;

把ADO.NET数据对象指定为源:有DataTable和DataView等对象;

使用XmlDataProvider把XML数据指定为Source;

把以来对象指定为源;

把容器的DataContext指定为源;

通过ElementName指定源:用于XAML中;

通过Binding的RelativeSource属性相对指定Source:当控件需要关注自己的、自己容器的或者自己内部元素的某个值就需要使用到这个属性;

把ObjectDataProvider对象指定为源;

把使用LINQ检索得到的数据对象作为源。

使用DataContext作为Binding的源:

DataContext是定义在WPF控件基类FrameworkElement中,因此所有WPF控件都有这个属性。

简单例子:

<Windowx:Class="BindBasicTest.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:BindBasicTest"

Title="MainWindow"Height="150"Width="230">

<StackPanelHeight="100">

<StackPanel.DataContext>

<local:StudentId="100"Name="LiLin"Age="18"></local:Student>

</StackPanel.DataContext>

<TextBoxText="{BindingPath=Id}"Margin="5"></TextBox>

<TextBoxText="{BindingPath=Name}"Margin="5"></TextBox>

<TextBoxText="{BindingPath=Age}"Margin="5"></TextBox>

</StackPanel>

</Window>

使用集合对象作为列表控件的ItemsSource:

列表控件都是派生自ItemsControl类,则都继承了ItemsSource这个属性。ItemsSource属性可以接受一个IEnumerable接口的派生类。只要为ItemsControl对象设置ItemsSource属性值,ItemsSource就会自动迭代其中的数据。

例子:

XAML设计:

StackPanelBackground="LightBlue">

<TextBlockText="StudentID"FontWeight="Bold"Margin="5"></TextBlock>

<TextBoxx:Name="txtBoxId"Margin="5"></TextBox>

<TextBlockText="StudentList"FontWeight="Bold"Margin="5"></TextBlock>

<ListBoxx:Name="listBoxStudent"Height="80"></ListBox>

</StackPanel>
后台代码:

publicMainWindow()

{

InitializeComponent();


List<Student>stu_list=newList<Student>()

{

newStudent(){Id=0,Name="LiLin",Age=18},

newStudent(){Id=1,Name="LinLi",Age=20},

newStudent(){Id=2,Name="LLiin",Age=24},

newStudent(){Id=3,Name="Tom",Age=27},

newStudent(){Id=4,Name="Tim",Age=19},

newStudent(){Id=5,Name="Luke",Age=23},

};


this.listBoxStudent.ItemsSource=stu_list;

this.listBoxStudent.DisplayMemberPath="Name";


this.txtBoxId.SetBinding(TextBox.TextProperty,newBinding("SelectedItem.Id"){Source=this.listBoxStudent});


}
this.listBoxStudent.DisplayMemberPath="Name";这是设置listbox显示字段,如果要显示多个或者全部字段呢。这就要使用到类型为DataTemplate的ItemTemplate属性(继承自ItemsControl类),通俗的说是换衣服。在XAML中修改代码,并把this.listBoxStudent.DisplayMemberPath="Name";删除:

<ListBoxx:Name="listBoxStudent"Height="80">

<ListBox.ItemTemplate>

<DataTemplate>

<StackPanelOrientation="Horizontal">

<TextBlockText="{BindingPath=Id}"Width="30"Foreground="Red"></TextBlock>

<TextBlockText="{BindingPath=Name}"Width="50"></TextBlock>

<TextBlockText="{BindingPath=Age}"Width="30"></TextBlock>

</StackPanel>

</DataTemplate>

</ListBox.ItemTemplate>

</ListBox>

注意事项:使用集合对象作为列表控件的ItemsSource时,一般会使用ObservableCollection<T>代替List<T>,理由是,ObservableCollection<T>实现了INotifyCollectionChanged和INotifyPropertyChanged接口。

使用ADO.NET对象作为Binding对象:

在WPF中支持列表控件与DataTable直接建立Binding。假设已经获得了一个DataTable的实例,数据跟以上的一样。现在Coding把它显示在ListBox中:

DataTabledt=Load();


this.listBoxStudent.ItemsSource=dt.DefaultView;

换件“衣服”:

<ListViewx:Name="listViewStudent"Height="120"Margin="5">

<ListView.View>

<GridView>

<GridViewColumnHeader="Id"Width="60"DisplayMemberBinding="{BindingId}"></GridViewColumn>

<GridViewColumnHeader="Name"Width="80"DisplayMemberBinding="{BindingName}"></GridViewColumn>

<GridViewColumnHeader="Age"Width="50"DisplayMemberBinding="{BindingAge}"></GridViewColumn>

</GridView>

</ListView.View>

</ListView>




有点注意的:ListView和GridView不是同一级别的控件。ListView是继承自ListBox,GridView是ViewBase的派生类,ListView的View属性是ViewBase的对象。因此,GridView可以作为ListView的View来使用。

如果想用更复杂的结构来表示标题或者数据,可以为GridViewColumn设置HeaderTemplate和CellTemplate属性,类型都是DataTemplate。

使用XML数据作为Binding的源:
现在程序中涉及到数据传输都离不开XML。XML文本是树形结构,可以方便地用于表示线性集合。

先Coding一个:

有这么一个Student.xml,

<?xmlversion="1.0"encoding="utf-8"?>

<StudentList>

<StudentId="1">

<Name>LiLin</Name>

</Student>

<StudentId="2">

<Name>Tom</Name>

</Student>

<StudentId="3">

<Name>Tim</Name>

</Student>

<StudentId="4">

<Name>Luke</Name>

</Student>

<StudentId="5">

<Name>Jake</Name>

</Student>

<StudentId="6">

<Name>LiLi</Name>

</Student>

</StudentList>
XAML:

<ListViewx:Name="listViewStudent"Height="120"Margin="5">

<ListView.View>

<GridView>

<GridViewColumnHeader="Id"Width="60"DisplayMemberBinding="{BindingXPath=@Id}"></GridViewColumn>

<GridViewColumnHeader="Name"Width="80"DisplayMemberBinding="{BindingXPath=Name}"></GridViewColumn>

</GridView>

</ListView.View>

</ListView>
后台:

mlDocumentxdoc=newXmlDocument();

xdoc.Load(@"C:\Student.xml");

XmlDataProviderxdp=newXmlDataProvider();

xdp.Document=xdoc;

xdp.XPath=@"/StudentList/Student";


this.listViewStudent.DataContext=xdp;

this.listViewStudent.SetBinding(ListView.ItemsSourceProperty,newBinding());

注意:XAML中DisplayMemberBinding="{BindingXPath=@Id}"和DisplayMemberBinding="{BindingXPath=Name}"之间的@差异,指明了关注的xml路径不同,使用@表示是XML元素的Attribute,不加的是指子集元素。

使用LINQ检索结果作为Binding的源:

因为LINQ查询结果是一个IEnumerable<T>类型的对象,而IEnumerable<T>继承了IEnumerable,所以它可以作为列表控件的ItemsSource来使用。

Coding:

List<Student>stu_list=newList<Student>()

{

newStudent(){Id=0,Name="LiLin",Age=18},

newStudent(){Id=1,Name="LinLi",Age=20},

newStudent(){Id=2,Name="LLiin",Age=24},

newStudent(){Id=3,Name="Tom",Age=27},

newStudent(){Id=4,Name="Tim",Age=19},

newStudent(){Id=5,Name="Luke",Age=23},

};


this.listViewStudent.ItemsSource=fromstuinstu_listwherestu.Age<=20selectstu;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: