wpf学习笔记 数据绑定
在软件和系统中,数据绑定应该是最常用的操作。UI展现、操作数据,都离不了绑定。
从最简单的绑定开始,我写了一个简单的类:
public class Student {
private int age;
public int Age
{
get { return age; }
set { age=value;
}
}
}
private int age;
public int Age
{
get { return age; }
set { age=value;
}
}
}
我要实现年龄的动态修改,所以对这个类进行了一些修改,使之能动态反映。
public class Student:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int age;
public int Age
{
get { return age; }
set { age=value;
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
}
}
}
}
{
public event PropertyChangedEventHandler PropertyChanged;
private int age;
public int Age
{
get { return age; }
set { age=value;
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
}
}
}
}
实现INotifyPropertyChanged后,Age属性的变化会触发PropertyChange事件,通知bingding对象更新数据。
在前台我用了一个TextBlock和一个Button,点击Button时Age+1,前台简单不表,直接上cs代码:
Student stu;
public AddAge()
{
InitializeComponent();
stu = new Student();
stu.Age = 1;
Binding bingding = new Binding();
bingding.Source = stu;
bingding.Path = new PropertyPath("Age");
BindingOperations.SetBinding(tb_Age, TextBlock.TextProperty, bingding);
}
public AddAge()
{
InitializeComponent();
stu = new Student();
stu.Age = 1;
Binding bingding = new Binding();
bingding.Source = stu;
bingding.Path = new PropertyPath("Age");
BindingOperations.SetBinding(tb_Age, TextBlock.TextProperty, bingding);
}
我给代码中加上了一个定时器,它就变成了一个很有意思的累加器:
System.Timers.Timer t = new System.Timers.Timer();
t.Interval = 1000;
t.Elapsed += new System.Timers.ElapsedEventHandler(Add);
t.Start();
t.Interval = 1000;
t.Elapsed += new System.Timers.ElapsedEventHandler(Add);
t.Start();
绑定里面很有趣的是,可以把某个控件作为数据源,实现一些非常好玩的功能,比如拖动滑块,动态显示进度:
实现代码如下:
<StackPanel>
<TextBox Height="23" Text="{Binding Path=Value, ElementName=sd_value,Mode=Default, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="12,12,0,0" Name="textBlock1" VerticalAlignment="Top" Width="254" />
<Slider Height="23" HorizontalAlignment="Left" Name="sd_value" Margin="10,10,0,0" VerticalAlignment="Top" Width="256" Maximum="100"/>
</StackPanel>
<TextBox Height="23" Text="{Binding Path=Value, ElementName=sd_value,Mode=Default, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="12,12,0,0" Name="textBlock1" VerticalAlignment="Top" Width="254" />
<Slider Height="23" HorizontalAlignment="Left" Name="sd_value" Margin="10,10,0,0" VerticalAlignment="Top" Width="256" Maximum="100"/>
</StackPanel>
如果把TextBlock写成Text="{Binding Path=Value.Lenth, ElementName=sd_value,Mode=Default, UpdateSourceTrigger=PropertyChanged}" ,可以检测输入框的字符长度,在某些场合还是很有用的。
在大多数的程序中,列表占了大部分的代码量,wpf中比较常用的是listbox。
<StackPanel x:Name="sp_List" Background="WhiteSmoke" Margin="5">
<ListBox Name="lb_List">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5">
<CheckBox Margin="5"></CheckBox>
<TextBlock Text="{Binding Path=Title}" Width="80" Margin="5"/>
<TextBlock Text="{Binding Path=Content}" Width="200" Margin="5"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<ListBox Name="lb_List">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5">
<CheckBox Margin="5"></CheckBox>
<TextBlock Text="{Binding Path=Title}" Width="80" Margin="5"/>
<TextBlock Text="{Binding Path=Content}" Width="200" Margin="5"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
在后台我直接把一个lst绑定给它,lb_List.ItemsSource = lst;
这是最简单的绑定。