Silverlight中数据绑定,须由自己决定要使用的绑定模式,在前面一篇文章中都是使用了默认模式OneTime
银光中支持3种模式
OneTime :仅在数据进行绑定时发生一次,以后更改绑定源对输出不产生任何影响
OneWay :数据绑定只在从绑定源到绑定目标这一个方向起作用,即更改绑定源会更改绑定目标,且不需要在代码中进行额外的处理
TwoWay :更改绑定源会更改绑定目标,反之亦然。
其中OneWay和TwoWay类似ASP.NET中的Eval与Bind绑定,需要注意的是,若使用这两者绑定模式,需要实现INotifyPropertyChanged接口
单向数据绑定
Xaml代码只是在之前的基础上添加了一个充当文本的按钮
<Grid x:Name="PersonalPanel" Background="White">
在此基础上完成单击时,使用reverse方法实现FirstName与LastName中的文本顺序颠倒
public void reverse()
{
char [] c=new char[this.FirstName.Length];
for (int i = 0; i < this.FirstName.Length; i++)
{
c[i] = this.FirstName[this.FirstName.Length - 1 - i];
}
this.FirstName = new String(c);
c = new char[this.LastName.Length];
for (int i = 0; i < this.LastName.Length; i++)
{
c[i] = this.LastName[this.LastName.Length - 1 - i];
}
this.LastName = new string(c);
}
接下来需要一个在更改属性时实现的公共事件:
public event PropertyChangedEventHandler PropertyChanged;
但是此事件无法自动使用,我们改写代码触发此事件,
private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
}
}
}
最后实现鼠标单击的事件处理程序 Person类文件的完整代码:
private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
}
}
}
//为进行演示,只对FirstName进行额外处理
public string LastName { get; set; }
public void reverse()
{
char [] c=new char[this.FirstName.Length];
for (int i = 0; i < this.FirstName.Length; i++)
{
c[i] = this.FirstName[this.FirstName.Length - 1 - i];
}
this.FirstName = new String(c);
c = new char[this.LastName.Length];
for (int i = 0; i < this.LastName.Length; i++)
{
c[i] = this.LastName[this.LastName.Length - 1 - i];
}
this.LastName = new string(c);
}
public event PropertyChangedEventHandler PropertyChanged;
不要忘记添加System.ComponentModel命名空间
后台代码:
public partial class MainPage : UserControl
{
private int pos = -1;
private Person[] persons;
public MainPage()
{
InitializeComponent();
persons = new Person[]
{
new Person{FirstName="David",LastName="Grenn"},
new Person{FirstName="Dam",LastName="White"},
new Person{FirstName="Tom",LastName="Smith"},
};
}
public void prev(object sender, MouseButtonEventArgs e)
{
if (pos > 0)
pos--;
bind();
}
public void next(object sender, MouseButtonEventArgs e)
{
if (pos < persons.Length - 1)
pos++;
bind();
}
private void bind()
{
PersonalPanel.DataContext = persons[pos];
}
private void reverse(object sender, MouseButtonEventArgs e)
{
persons[pos].reverse();
}
运行时,会发现当单击Reverse时,只有名字颠倒了顺序,但是如果移动到下一个(或上一个),然后返回到之前的记录,会发现两者都颠倒了,原因在于只有FirstName属性触发了PropertyChanged事件,因此只更新名字的显示,但是当前进或者后退时,数据总是会再次绑定到元素上,因此会出现两者全部颠倒的情况。
双向数据绑定
双向数据绑定可以使得显示数据的变化可以在原始数据中得到反映
为简化起见,在前面的示例中进行改写,只保留了其中关键的代码,主要是在绑定中添加了Mode枚举,我们把XAML代码修改为:
<Grid x:Name="PersonalPanel" Background="White">
<TextBox Name="textBlock3" Text="{Binding FirstName, Mode=TwoWay}" />
<TextBox Name="textBlock4" Text="{Binding LastName, Mode=TwoWay}" />
<Canvas Canvas.Left="120">
<Polygon Fill="Black" Points="0,5,10,0,10,10" MouseLeftButtonDown="prev"></Polygon>
<Polygon Fill="Black" Points="15,0,15,10,25,5" MouseLeftButtonDown="next"></Polygon>
</Canvas>
</Grid>
C#代码也进行了一点改变,lastname也实现了触发PropertyChanged事件
private string lastName;
public string LastName
{
get { return lastName; }
set {
lastName = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("LastName"));
}
}
}
其他代码部分则没有改变,运行时,当切换到某个字段时,(改变文本框内容后,需要使得文本框失去焦点),这时PropertyChanged事件会自动触发,
但是该事件不会在键入内容时立即触发,当单击下一条记录再返回时,因为使用了双向绑定,所以会自动传送给数据源。