分享
 
 
 

在完成所有绑定后仍然有许多要进行的操作

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

我们希望能够直接将对象和对象的集合绑定到 Avalon UI 元素。作为一个示例,以下代码显示了我们用于探究绑定在 Avalon 中数据的 Person 类。

class Person : IPropertyChange {

public event PropertyChangedEventHandler PropertyChanged;

void FirePropertyChanged(string propertyName) {

if( this.PropertyChanged != null ) {

PropertyChanged(this,

new PropertyChangedEventArgs(propertyName));

}

}

string name;

public string Name {

get { return this.name; }

set {

this.name = value;

FirePropertyChanged("Name");

}

}

int age;

public int Age {

get { return this.age; }

set {

this.age = value;

FirePropertyChanged("Age");

}

}

...

}

IPropertyChange 接口由 Person 类实现,以通知绑定到实例的任意控件,其中一个属性已经更改。相反,公共属性让绑定控件的数据可以访问每个属性的当前值,并应用 UI 中发起的变化。图 1 中的 Name 和 Age TextBox 控件显示了 Person 对象的一个实例,该对象绑定到每个控件的 TextContent 属性。

当前项目

在 Name 和 Age TextBox 控件绑定到单个对象时,Persons ListBox 控件绑定到 Person 对象的集合中。由于 ListBox 中的选择发生了变化,当前项目 也发生变化,所有绑定控件的数据按照它们认为合适的方式进行处理。例如,如图 1 所示,通过突出显示其列表中的对象,ListBox 反映了当前项目,同时 TextBox 将仅显示当前项目的绑定属性值。当前,跟踪哪个项目是由数据的视图 来管理的。视图是一个位于数据和共享数据视图的控件之间的对象,管理着像当前项目、筛选和排序这样的操作。实际上,在 Avalon 中,完全不需要绑定到数据,而是使用程序员或 Avalon 提供的数据视图。

class Window1 : Window {

ArrayListDataCollection persons =

new ArrayListDataCollection();

void Window1_Loaded(object sender, EventArgs e) {

persons.Add(new Person("John", 10));

persons.Add(new Person("Tom", 8));

this.DataContext = this.persons;

showButton.Click += showButton_Click;

birthdayButton.Click += birthdayButton_Click;

addPersonButton.Click += addPersonButton_Click;

}

void showButton_Click(object sender, ClickEventArgs e) {

ListCollectionView view =

(ListCollectionView)Binding.GetView(persons);

Person person = (Person)view.CurrentItem.Current;

MessageBox.Show(

string.Format("Name is '{0}' and you are {1} years old",

person.Name,

person.Age));

}

...

}

这个 Show 按钮单击处理程序代码调用 Binding 对象上的静态 GetView 方法,该对象会返回与 person 数据相关联的默认视图。回忆 persons 字段是 ArrayListDataCollection 的实例(您将会想到我的上一篇文章),它是 ArrayList 类的子类,该类添加 ICollectionChange 接口的实现,以便绑定到集合的控件(如 Persons ListBox)可以注册集合本身更改时的通知。

如果已经获得要绑定的项目集合,从 GetView 方法返回的视图对象的类型将成为 ListCollectionView 类的派生,它将进一步向下延续基类 CollectionView 的继承链:

namespace System.Windows.Data {

public class ListCollectionView :

ContextAffinityCollectionView, ICurrentItem, IComparer {

public override SortDescription[] Sort { get; set; }

public override bool Contains(object item);

public ListCollectionView(System.Collections.IList list);

public override int Count { get; }

public override void Refresh();

public override bool ContainsItem(object item);

public override IEnumerator GetEnumerator();

public override int IndexOf(object item);

public IContains CustomFilter { get; set; }

public override bool CanSort { get; }

public IComparer CustomSort { get; set; }

}

public abstract class ContextAffinityCollectionView :

CollectionView {

}

}

namespace System.ComponentModel {

public abstract class CollectionView :

IEnumerable, ICollectionChange {

public virtual ICurrentItem CurrentItem { get; }

...

}

}

当用户更改绑定 ListBox 中的选择时,CollectionView 基类中的 CurrentItem 属性发生变化,然后绑定控件的其他数据使用该属性来显示它们的内容。图 2 显示了这种关系。

图 2. 项目、当前项目、视图和绑定控件

该视图还用于比只维护当前项目更不常用的任务,例如排序和筛选。

排序

由于视图始终位于绑定控件的数据和数据本身之间。这意味着可能会贸然出现我们不希望显示的数据(这称为筛选,且它将被直接覆盖),并且可能会更改数据显示的顺序(排序)。最简单的排序方法就是设置视图的 Sort 属性:

void sortButton_Click(object sender, ClickEventArgs e) {

ListCollectionView view =

(ListCollectionView)Binding.GetView(persons);

if( view.Sort.Length == 0 ) {

view.Sort = new SortDescription[] {

new SortDescription("Name", ListSortDirection.Ascending),

new SortDescription("Age", ListSortDirection.Descending),

};

}

else {

view.Sort = new SortDescription[0];

}

view.Refresh();

}

请注意由要进行排序的属性名称和顺序(升序或降序)构建的 SortDescription 对象数组的使用。还要注意对视图对象上的 Refresh 的调用。当前,这要求使用视图的新属性来刷新绑定控件(尽管希望在 Longhorn 的将来的版本中不要求对 Refresh 显式调用)。

SortDescription 对象的数组应该涵盖大多数情况,但是如果想要更多的控件,可以通过实现 IComparer 接口为视图提供自定义排序对象。

void sortButton_Click(object sender, ClickEventArgs e) {

ListCollectionView view =

(ListCollectionView)Binding.GetView(persons);

if( view.CustomSort == null ) {

view.CustomSort = new PersonSorter();

}

else {

view.CustomSort = null;

}

view.Refresh();

}

class PersonSorter : IComparer {

public int Compare(object x, object y) {

Person lhs = (Person)x;

Person rhs = (Person)y;

// Sort Name ascending and Age descending

int nameCompare = lhs.Name.CompareTo(rhs.Name);

if( nameCompare != 0 ) return nameCompare;

int ageCompare = 0;

if( lhs.Age < rhs.Age ) ageCompare = -1;

else if( lhs.Age rhs.Age ) ageCompare = 1;

return ageCompare;

}

}

这个自定义排序实现碰巧与以前排序说明的集合具有相同的行为,但您可以完成任何想要进行的操作来确定对象在数据绑定控件中的存储方式。此外,将视图的 Sort 属性设置为 SortDescription 对象的空数组,并且将视图的 CustomSort 属性设置为 null,可以关闭排序。

筛选

仅仅因为所有对象按照令您高兴的某个顺序显示并不意味着您希望显示所有对象。对于出现在数据中但不属于该视图的那些恶意对象,我们需要为视图提供一个 IContains 接口的实现:

void filterButton_Click(object sender, ClickEventArgs e) {

ListCollectionView view =

(ListCollectionView)Binding.GetView(persons);

if( view.CustomFilter == null ) {

view.CustomFilter = new PersonFilter();

}

else {

view.CustomFilter = null;

}

view.Refresh();

}

class PersonFilter : IContains {

public bool Contains(object item) {

Person person = (Person)item;

// Filter adult Persons

return person.Age = 18;

}

}

这种筛选

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有