您的位置:首页 > 其它

案例分析Silverlight中的Binding技术

2011-09-06 19:49 417 查看
在WPF(WindowsPresentationFoundation)中,提供了数据的binding技术,使显示和交互数据变得简单,并与数据的管理独立。Databinding可以同步两个不同对象的两个属性值。例如,我们需要在界面上显示一个内容动态变化的文本框,我们可以建立一个binding对象,把文本框的值和一个变量绑定,这样每次修改这个变量或者修改文本框的值时,另一端的内容就可以自动同步。在Silverlight中,由于XAML这种标记语言的运用,使得binding变得更加简单了。只需要用简短的一个属性值就可以定义一个binding。

为了更形象一点,我们还是用一个例子来深入binding技术。假设现在在联网游戏对战平台中,需要一个文本标签,显示我方的人数。此外还有一个列表,显示一个服务器上的所有在线玩家。大体界面如下图所示:





现在我们假设游戏后台有一个Game类,其中包含了我方人数、在线玩家的信息,这些数据由其他模块提供。我们需要将它们独立于数据管理部分显示出来。

先看看我方玩家数目的显示,为简化问题,假设Game类中有一个整型变量:

publicintTeammateCount;

存储了表示我方人数的字符串。为了实现binding,首先必须让Game类继承INotifyPropertyChanged接口,此接口提供了PropertyChanged事件。

publicclassGame:INotifyPropertyChanged { publiceventPropertyChangedEventHandlerPropertyChanged; //Blablabla }

接下来,需要在TeammateCount的值发生改变的时候,触发这一事件。因此要改变TeammateCount属性set方法的行为:

privateint_TeammateCount; publicintTeammateCount { get{return_TeammateCount;} set { _TeammateCount=value; NotifyPropertyChanged("TeammateCount"); } } publicvoidNotifyPropertyChanged(stringpropertyName) { if(PropertyChanged!=null) { PropertyChanged(this, newPropertyChangedEventArgs(propertyName)); } }

上面的工作是为了使binding的源的值发生改变时,能及时发出事件,通知binding对象。如果binding的源所在的类是UIElement的子类,这个工作也可以交给DependencyProperty来完成。

下面就很简单了,只需要在XAML中加上相关的binding,并在C#代码中指定DataContent即可。

<sdk:LabelName="lblTeammateCount" Content="{BindingTeammateCount}"/>

Gamegame=newGame();

publicMainPage()
{
InitializeComponent();
lblTeammateCount.DataContext=game;
}
在Test按钮中加一小段代码测试一下

privatevoidbtnTest_Click(objectsender,RoutedEventArgse)
{
game.TeammateCount=123;
}
点击按钮之后,发现显示的结果立刻发生了变化,我们的第一个小实验圆满结束。





下面我们来增加问题的难度,更深入地学习binding。假设现在我们并不是直接输出人数的阿拉伯数字形式,而是逐位转换成汉字呢?这时,就需要借助binding的数据转换(DataConversions)了。为了实现转换,我们需要定义一个继承IValueConverter接口的类NumberConverter:

publicclassNumberConverter:IValueConverter
{
staticStringzhNum="〇一二三四五六七八九";
publicobjectConvert(objectvalue,TypetargetType,objectparameter,CultureInfoculture)
{
Strings="";
foreach(Charcinvalue.ToString())
if(c>='0'&&c<='9')
s+=zhNum[c-'0'];
returns;
}

publicobjectConvertBack(objectvalue,TypetargetType,objectparameter,CultureInfoculture)
{
thrownewNotImplementedException();
}
}
然后,再界面的XAML中加入相应实现bindingconverter的代码:

<UserControl.Resources>
<local:NumberConverterx:Key="numberConverter"/>
</UserControl.Resources>

<sdk:LabelName="lblTeammateCount"
Content="{BindingTeammateCount,Converter={StaticResourcenumberConverter}}"/>
如此即可实现带有数据转换的binding。





作为最后一个例子,我们来看看如何把Listbox的内容binding到一个Collection。Silverlight中已经实现了一个ObservableCollection类,继承了INotifyCollectionChanged接口,当Collection的内容发生改变时,自动触发CollectionChanged事件。因此,我们不需要像上面一样专门写一个类,直接使用现成的就可以了。

首先,需要定义玩家的数据类型:

publicclassPlayer
{
publicintID{get;set;}
publicStringName{get;set;}

publicPlayer(intid,Stringname)
{
ID=id;
Name=name;
}
}
注意这里必须要为成员定义public的get方法,否则binding会失败。

接下来,在Game类中添加Players成员:

publicObservableCollection<Player>Players;
修改界面中ListBox的定义:

<ListBoxName="lstPlayers">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanelOrientation="Horizontal">
<TextBlockText="{BindingID}"/>
<TextBlockText=","/>
<TextBlockText="{BindingName}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
这里定义了ListBox中每个Item的显示方式,bind到什么路径的信息。

然后在主界面的构造函数中添加:

lstPlayers.ItemsSource=game.Players;
指定ListBox的数据源。如此即可完成整个Collection的binding过程,当Players发生改变时,界面显示也会改变。





菜鸟初学Silverlight,还望高手多多指教!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: