来自《深入浅出WPF》(刘铁猛)读书笔记
J)使用LINQ检索结果作为Binding的源
LINQ的查询结果是一个IEnumerable<T>类型对象,而IEnumerable<T>有派生自IEnumerable,所以它可以作为列表控件的ItemSource来使用。
创建一个名为Student的类:
public class Student
{
public int id{get;set;}
pblic string Name{get;set;}
public int Age{get;set;}
}
设计UI用于在Button被单击的时候显示一个Student集合类型对象。
查询集合对象:要从一个已经填充好的List<Student>对象中检索出所有名字以字母T开头的学生:
this.listViewStudents.ItemsSource=from stu in stuList where stu.Name.StartsWith("T") select stu;
如果数据存放在一个已经填充好的DataTable对象里,则:
DataTable dt=this.GetDataTable();
this.listViewStudents.ItemsSource=from row in dt.Rows.Cast<DataRow>()
where Convert.ToString(row["Name"]).StartsWith("T")
select new Student()
{
Id=int.Parse(row["Id"].ToString()),
Name=row["Name"].ToString(),
Age=int.Parse(row["Age"].ToString())
};
如果数据存储在XML文件里(D:\RawData.xml),则:
XDocument xdoc=XDocument.Load(@"D:\RawData.xml");
this.listViewStudents.ItemsSource=from element in xdoc.Descendants("Student")
where element.Attribute("Name").Value.StartsWith("T")
select new Student()
{
Id=int.Parse(element.Attribute("Id").Value),
Name=element.Attribute("Name").Value,
Age=int.Parse(element.Attribute("Age").Value)
};
K)使用ObjectDataProvider
把对象作为数据源提供给Binding。BindsDirectlyToSource=true告诉Binding对象只负责把从UI元素收集到的数据写入其直接Source(即ObjectDataProvider对象)而不是被ObjectDataProvider对象包装着的Calculator对象(通过Calculator计算2个textbox中的值并写入第三个TextBox中)。
在把ObjectDataProvider对象当作Binding的Source来使用时,这个对象本身就代表了数据,所以这里的Path使用的是"."而非其他Data属性。
ObjectDataProvider的methodParameters不是依赖属性,不能作为Binding的目标;
数据驱动UI的理念要求尽可能的使用数据对象作为Binding的Source,而把UI元素当作Biinding的Target。
L)使用Binding的RelativeSource
有明确的数据来源时可以通过Source或ElementName赋值的办法让Binding与之关联,如果不能确定Source的对象叫什么名字,但知道它与作为Binding目标的对象在UI布局上有相对关系,这时就要使用Binding的RelativeSource属性。
RelativeSource类的Model属性的类型是RelativeSourceModel枚举:
public enum RelativeSourceMode
{
PreviousData,
TemplateParent,
Self,
FindAncestor,
};
还有3个静态属性:PreviousData,Self,TemplateParent,类型都是RelativeSource。这三个静态属性就是创建一个RelativeSource实例,把实例的Mode属性设置为相应的值,然后返回这个实例。