转自:http://blog.csdn.net/lisenyang/article/details/18312199

1.集合作为数据源

首先我们先创建一个模型类

 public class Student
{
public int ID { get; set; }
public String Name { get; set; }
}

然后我们创建我们的页面布局

 <StackPanel Width="" Height="" HorizontalAlignment="Left">
<ListView Name="listView1">
<ListView.View>
<GridView>
<GridViewColumn Header="编号" DisplayMemberBinding="{Binding ID}" Width=""></GridViewColumn>
<GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Name}" Width=""></GridViewColumn>
</GridView>
</ListView.View>
</ListView> </StackPanel>

在这里我们使用了ListView控件和GridView控件来显示数据,这两个控件从表面来看应该属于同一级别的控件。实际上并非如此!ListView是ListBox的派生类,而GridView是ViewBase的派生类,ListView中的View是一个ViewBase对象,所以,GridView可以做为ListView的View来使用而不能当作独立的控件来使用。这里使用理念是组合模式,即ListView由一个View,但是至于是GridVIew还是其它类型的View,由程序员自己选择。其次,GridView的内容属性是Columns,这个属性是GridViewColumnCollection类型对象。因为XAML支持对内容属性的简写,可以省略<GridView.Columns>这层标签,直接在GridView内部定义<GridViewColumn>对象,GridViewColumn中最重要的一个属性是DisplayBinding(类型是BindingBase),使用这个属性可以指定这一列使用什么样的Binding去关联数据-----这与ListBox有些不同,ListBox使用的是DisplayMemberPath属性(类型是String)。如果想用更复杂的结构来表示这一标题或数据,则可为GridViewColumn设置Head Template和Cell Template,它们的类型都是DataTemplate

接下来下后台代码

 IList<Student> list = new ObservableCollection<Student>()
{
new Student(){ID=,Name="狗娃"},
new Student(){ID=,Name="狗剩"},
new Student(){ID=,Name="铁蛋"}
};
this.listView1.ItemsSource = list;

只需在构造函数中创建对象并绑定到ListView上即可,然后运行就可以看到已经绑定完毕

接下来看一下ObservableCollection这个集合,我们可以看到在这里使用的是ObservableCollection集合而并非平常的List集合,那么为什么呢,因为ObservableCollection集合实现了INotifyCollectionChanged接口,也就是可以双向绑定。

2.ADO.NET中DataTable对象做为数据源

在wpf中,是允许将DataTable直接做为Binding的数据源的,下面以一个例子做为参考

控件还可以用上面的控件,只需该数据源即可

首先先创建一个用于创建DataTable的方法

   public DataTable CreateDt()
{
DataTable dt = new DataTable();
DataColumn[] dc = new DataColumn[]
{
new DataColumn("ID"),
new DataColumn(){ColumnName="Name"}
};
dt.Columns.AddRange(dc);
return dt;
}

然后再构造函数中创建DataTable,赋予值并绑定即可

  DataTable dt = CreateDt();
DataRow dr = dt.NewRow();
dr[] = ;
dr[] = "狗娃";
dt.Rows.Add(dr); dr = dt.NewRow();
dr[] = ;
dr[] = "狗剩";
dt.Rows.Add(dr); dr = dt.NewRow();
dr[] = ;
dr[] = "铁蛋";
dt.Rows.Add(dr);
//将数据源设置为Dt的视图
this.listView1.ItemsSource = dt.DefaultView;

3.使用XML数据作为数据源

WPF提供了两套处理XML的类库:

  1.符合DOM(Document Object Model 文档对象模式)标准类库:XmlDocument.XmlElement,XmlNode等类,这套类型特点中规中矩,功能强大,但也背负了太多的XML传统和复杂

  2.以LINQ(Language-Intergrated Query 语言集成查询)为基础的类库,包括:XDocument,XElement,XNode,XAttribute等类,这套类库特点是可以通过LINQ进行查询和操作,方便快捷

首先使用第一种方案

    先创建一个XML文件

<?xml version="1.0" encoding="utf-8" ?>
<StudentList>
<Student id="">
<Name>狗娃</Name>
</Student>
<Student id="">
<Name>狗剩</Name>
</Student>
<Student id="">
<Name>铁蛋</Name>
</Student>
</StudentList>

然后创建XAML

 <StackPanel Width="" Name="stackPanel1">
<ListView Name="listView1">
<ListView.View>
<GridView>
<GridViewColumn Header="编号" DisplayMemberBinding="{Binding XPath=@id}"> </GridViewColumn>
<GridViewColumn Header="姓名" DisplayMemberBinding="{Binding XPath=Name}"> </GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>

注意:XML绑定不是使用Path,而是XPath

 XmlDocument doc = new XmlDocument();
doc.Load(@"C:\资料\f盘\代码\c#\WPF\TreeView\TestSource\Students.xml");
//通过XmlDataProvider进行绑定数据
XmlDataProvider dp = new XmlDataProvider();
dp.Document = doc;
dp.XPath = @"StudentList/Student";
this.listView1.SetBinding(ListView.ItemsSourceProperty, new Binding() { Source=dp});

绑定XMl使用到了XmlDataProvider,这个类是将XMl做为数据源源的一种快捷方式.XmlDataPrivider有个Source属性,可以使用它直接指定XML文档地址(无论XML文档是存储在本地还是网络位置),所以也可以这么写

 XmlDataProvider dp = new XmlDataProvider();
dp.Source = new Uri(@"C:\资料\f盘\代码\c#\WPF\TreeView\TestSource\Students.xml");
dp.XPath = @"StudentList/Student";
this.listView1.SetBinding(ListView.ItemsSourceProperty, new Binding() { Source=dp});

4.使用LINQ做为数据源

从3.0版本,.NET Framework开始支持LINQ,使用LINQ,可以方便的操作集合对象,LINQ查询结果是一个IEnumerable<T>类型对象,而IEnumerable<T>又派生自IEnumerable,所以可以作为列表控件的Items Source使用。

现在还还用刚开始创建的那个Student模型类和XAML代码,

public class Student
{
public int ID { get; set; }
public String Name { get; set; }
}
<StackPanel Height="" Width="" HorizontalAlignment="Left">
<ListView Name="listView1">
<ListView.View>
<GridView>
<GridViewColumn Header="编号" DisplayMemberBinding="{Binding ID}" Width=""></GridViewColumn>
<GridViewColumn Header="姓名" DisplayMemberBinding="{Binding Name}" Width=""></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>

我们只需更改数据源即可

 List<Student> stus = new List<Student>()
{
new Student(){ID=,Name="狗娃"},
new Student(){ID=,Name="铁蛋"},
new Student(){ID=,Name="狗剩"}
};
this.listView1.ItemsSource = from stu in stus where stu.Name.StartsWith("狗") select stu;

还可以将数据放在DataTable中

 DataTable dt = CreateDt();
DataRow dr = dt.NewRow();
dr[] = ;
dr[] = "狗娃";
dt.Rows.Add(dr); dr = dt.NewRow();
dr[] = ;
dr[] = "狗剩";
dt.Rows.Add(dr); dr = dt.NewRow();
dr[] = ;
dr[] = "铁蛋";
dt.Rows.Add(dr); this.listView1.ItemsSource = from row in dt.Rows.Cast<DataRow>()
where (row["Name"] as String).StartsWith("狗")
select new Student
{
ID = Convert.ToInt32(row["ID"]),
Name = row["Name"] as String
};

又或者使用XML

 XDocument xd = XDocument.Load(@"C:\资料\f盘\代码\c#\WPF\TreeView\TestSource\Students.xml");
this.listView1.ItemsSource = from ele in xd.Descendants("Student")
where (ele.Elements().First()).Value.StartsWith("狗")
select new Student
{
ID = Convert.ToInt32(ele.Attribute("id").Value),
Name = ele.Elements().First().Value

5.ObjectDataProvider做为数据源

理想情况下,上游程序员将类设计好,使用属性把数据暴露出来,下游程序员将这些类作为Binding的Source,把属性做为Binding的Path来消费。但很难保证一个类的属性都暴露出来,例如需要的数据可能是方法的返回值。而重新设计底层类的风险会比较高,况且有可能引用的类库情况我们不可能更改已经便宜好的类,这时候就需要使用ObjectDataProvider来包装做为Binding源的数据对象。

ObjectDataProvider顾名思义就是把对对象做为数据源提供给Binding。上面使用的XmlDataProvider,这两个类的父类都是DataSourceProvider抽象类。

现在做一个这样例子。

有一个Calculator类,它具有一个加法方法

class Caculate
{
public string Add(string arg1, string arg2)
{
double x = ;
double y = ;
double z = ;
if (double.TryParse(arg1, out x) && double.TryParse(arg2, out y))
{
z = x + y;
return z.ToString();
}
return "Iput Error";
} }

然后在XAML中创建三个TextBox框

<StackPanel Height="" Width="" HorizontalAlignment="Left">
<TextBox Name="txtBox1" Width="" HorizontalAlignment="Left"></TextBox>
<TextBox Name="txtBox2" Width="" Margin="0 10" HorizontalAlignment="Left"></TextBox>
<TextBox Name="txtBox3" Width="" Margin="0 10" HorizontalAlignment="Left"></TextBox>
</StackPanel>

要实现的需求就是通过Caculate方法实现第三个文本框是前两个之和,也就是我们需要将前两个文本框绑定到Add方法的两个参数,第三个绑定到返回值上。

然后我们在构造函数中编写后台代码

  ObjectDataProvider odp = new ObjectDataProvider();
//设置用于绑定源的对象
odp.ObjectInstance = new Caculate();
//设置调用方法的名称
odp.MethodName = "Add";
//添加方法参数
odp.MethodParameters.Add("");
odp.MethodParameters.Add("");
//绑定参数到txtBox1和txtBox2
this.txtBox1.SetBinding(TextBox.TextProperty, new Binding("MethodParameters[0]") { Source = odp, BindsDirectlyToSource = true, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
this.txtBox2.SetBinding(TextBox.TextProperty, new Binding("MethodParameters[1]") { Source = odp, BindsDirectlyToSource = true, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
//绑定结果
this.txtBox3.SetBinding(TextBox.TextProperty, new Binding(".") { Source = odp});

先来分析一下上面代码。ObjectDataProvider类的作用是包装一个以方法暴露数据的对象,这里就先创建一个ObjectDataProvider的对象.然后用一个Caculate对象做为ObjectInstance对象复制。这就是把Caculate对象包装在了ObjectDataProvider里面。接着使用MethodName属性指定调用的Caculate对象中Add的方法。问题来了,如果Caculator有多个构造器参数的方法Add应该如何区分?我们知道,重载方法的区别在于参数列表,紧接着两句就是向MethodParameter属性里面加入两个string类型的参数,这就相当于告诉ObjectDataProvider对象去调用Caculator对象中具有两个string类型参数的Add方法,换句话说,MethodParameter对于参数的感应是非常敏感的。

准备好数据源之后,我们准备创建Binding。前面我们已经讲过使用索引器作为Binding的Path,第一个Binding它的Source是一个ObjectDataProvider对象,Path是ObjectDataProvider中MethodParameters所引用的第一个元素。BindsDirectlyToSource这句话是告诉Binding只是将UI上的值传递给源而不是被ObjectDataProvider包装的Caculator,同时UpdateSourceTrigger设置为UI只要一有变化就更新Source。第二个Binding只是对第一个的翻版,只是把Path属性指向了第二个元素。第三个binding仍然使用ObjectDataProvider作为Source,但使用“.”作为Path----前面讲过,当数据源本身就是数据的时候就用“.”来做为Path,在XAML中"."可以不写。

注意:  在ObjectDataProvider对象作为Binding的Source的时候,这个对象本身就代表了数据,所以这里的Path使用的“.”,而不是Data属性。

6.使用RelativeSource当绑定源

当一个Binding有明确的来源的时候,我们可以通过Source或者ElementName赋值的办法让Binding与之关联。有些时候我们不能确定作为Source对象叫什么名字,但是我们知道它与做为Binding目标对象在UI上的相对关系,比如控件自己关联自己的某个数据,关联自己某级容器的数据,这时候就需要用到Binding的RelativeSource属性。

RelativeSource属性的类型是RelativeSource类,通过这个类的几个静态或者非静态的属性我们可以控制它搜索相对数据源的方式。

 <StackPanel x:Name="stackPanel1" Margin="">
<StackPanel x:Name="stackPanel2" Margin="">
<Grid Name="grid2">
<TextBox Name="txtBox1" Width="" Height="" HorizontalAlignment="Left"></TextBox>
</Grid>
</StackPanel>
</StackPanel>

我们看下上面结构   这个XAML结构为   StackPanel1----StackPanel2---Grid2---TextBox  。然后以相对路径来为TextBox进行绑定

RelativeSource relative = new RelativeSource(RelativeSourceMode.FindAncestor);
//设置要查找的上级级别
relative.AncestorLevel = ;
//设置要查找的类型
relative.AncestorType = typeof(StackPanel);
Binding binding = new Binding("Name")
{//设置相对绑定的数据源
RelativeSource = relative
};
this.txtBox1.SetBinding(TextBox.TextProperty, binding);

然后再观察以上代码。相对绑定源类为RelativeSource类,这个类构造可以放一个RelativeSourceMode枚举,这个枚举描述与绑定目标的位置相对的绑定源位置。枚举值有四个

  • PreviousData:当前显示向列表的上一个数据项
  • TemplateParent:引用应用了模板的元素,其中此模板中存在数据绑定元素。
  • Self:引用正在绑定的元素,允许你该元素的一个属性绑定到同一元素的其他属性上。  
  • FindAncestor:引用数据绑定元素的父链中的上级。 可用于绑定到特定类型的上级或其子类

在这里设置为了FindAncestor. 然后为RelativeSource设置查找的级别和查找的类型。这里是先筛选类型,再筛选级别,比如现在查找的是深度为1的StackPanel。所以选中的是StackPanel2 而不是Grid2 。最后将RelativeSource对象设置为Binding的数据源

  注意:设置数据源使用的是RelativeSource而不是Source

WPF Binding学习(四) 绑定各种数据源的更多相关文章

  1. WPF Binding学习(二)

    Binding作为数据的桥梁,连通业务逻辑层的对象(源对象)和UI的控件对象(目标对象).在这座桥梁上,我们不仅可以控制在源对象与目标对象是双向通行还是单向通行.还可以控制数据的放行时机,甚至可以在这 ...

  2. WPF Binding学习(三)

    转自;http://blog.csdn.net/lisenyang/article/details/18312199 1.控件与控件间的双向绑定 WPF还支持控件作为数据源, <TextBox ...

  3. WPF项目学习.四

    信息收录项目 版权声明:本文为博主初学经验,未经博主允许不得转载. 一.前言 记录在学习与制作WPF过程中遇到的解决方案.  需求文案.设计思路.简要数据库结构.简要流程图和明细代码,动图细化每步操作 ...

  4. WPF Binding(四种模式)

    在使用Binding类的时候有4中绑定模式可以选择 BindingMode TwoWay 导致对源属性或目标属性的更改可自动更新对方.此绑定类型适用于可编辑窗体或其他完全交互式 UI 方案. OneW ...

  5. WPF+MVVM学习总结 DataGrid简单案例

    一.WPF概要 WPF(Windows Presentation Foundation)是微软推出的基于Windows 的用户界面框架,属于.NET Framework 3.0的一部分.它提供了统一的 ...

  6. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  7. WPF绑定各种数据源之object数据源

    一.WPF绑定各种数据源索引 WPF 绑定各种数据源之Datatable WPF绑定各种数据源之object数据源 WPF绑定各种数据源之xml数据源 WPF绑定各种数据源之元素控件属性 Bindin ...

  8. WPF绑定各种数据源之xml数据源

    一.WPF绑定各种数据源索引 WPF 绑定各种数据源之Datatable WPF绑定各种数据源之object数据源 WPF绑定各种数据源之xml数据源 WPF绑定各种数据源之元素控件属性 Bindin ...

  9. WPF Binding ElementName方式无效的解决方法--x:Reference绑定

    原文:WPF Binding ElementName方式无效的解决方法--x:Reference绑定 需求: 背景:Grid的有一个TextBlock name:T1和一个ListBox,ListBo ...

随机推荐

  1. C#基础(201)--常量枚举

    本文知识点: 1.掌握常量的定义和使用方法 2.理解枚举的作用和特点 3.掌握枚举的使用方法 1.1.常量的定义语法 const  数据类型   常量名称  =  值: 1.2.常见错误 1.3常量的 ...

  2. AI在汽车中的应用:实用深度学习

    https://mp.weixin.qq.com/s/NIza8E5clC18eMF_4GMwDw 深度学习的“深度”层面源于输入层和输出层之间实现的隐含层数目,隐含层利用数学方法处理(筛选/卷积)各 ...

  3. 7.Odoo产品分析 (二) – 商业板块(3) –CRM(1)

    查看Odoo产品分析系列--目录 CMR:Customer Relationship Management.企业为提高核心竞争力,利用相应的信息技术以及互联网技术协调企业与顾客间在销售.营销和服务上的 ...

  4. Mybatis使用动态代理实现拦截器功能

    1.背景介绍 拦截器顾名思义为拦截某个功能的一个武器,在众多框架中均有“拦截器”.这个Plugin有什么用呢?或者说拦截器有什么用呢?可以想想拦截器是怎么实现的.Plugin用到了Java中很重要的一 ...

  5. mysql左连接

    举个例子说明: select d.id, d.uid,d.username,d.dateline, d.message,d.replynum, c.picid, c.filename from doi ...

  6. Android 源码编译之旅

    目录 前言 背景 安装软件 正文 Mac 分区 移动硬盘分区 Repo 下载源码 编译 源码导入 Android Studio 查看 碰到的问题 Could not find a supported ...

  7. L2-024. 部落

    在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈.我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同 ...

  8. 你的leader还在考核你的千行代码Bug率吗?

    管理学大师德鲁克说:你如果你无法度量它,就无法管理它.要想做有效的管理,就很难绕开度量的问题. 软件开发的过程或者技术团队的管理也存在着如何去合理的度量效率的问题.而度量是把双刃剑,度量具有极强的引导 ...

  9. Using IntelliJ IDEA as the Vim Editor

    转载自https://www.jetbrains.com/help/idea/using-intellij-idea-as-the-vim-editor.html This feature is on ...

  10. [20190401]那个更快的疑问.txt

    [20190401]那个更快的疑问.txt --//前一阵子,做了11g于10g下,单表单条记录唯一索引扫描的测试,摘要如下:--//参考链接:http://blog.itpub.net/267265 ...