推荐阅读:
WPF 之 Binding 数据驱动UI—实战 https://blog.csdn.net/litao2/article/details/62218220
WPF 之 Binding 数据驱动UI https://blog.csdn.net/litao2/article/details/18311991
WPF 使用ValidationRule进行表单数据验证 https://blog.csdn.net/litao2/article/details/56283687
一、Data Binding在WPF中的地位
DataBinding 把UI元素一一与数据关联上(以数据为中心的星形结构),当数据发生变化后,这些UI元素会同步显示这一变化。
程序的逻辑层就像是一个强有力的引擎一直在运作,用加工好的数据驱动用户界面用文字、图形、动画等形式把数据显示出来,这就是数据驱动UI。
DataBinding 比作数据桥梁,那么它的两端分别是Binding的源(Source)和目标(Target)。Binding的源是逻辑层对象,Binding的目标是UI层的控件对象。想象 DataBinding 这座桥梁上铺设了高速公路,我们不但可以控制公路是在源与目标之间双向通行还是某个方向的单行道,还可以控制对数据放行的时机,甚至可以在桥上架设一些 “关卡” 用来转换数据类型或检验数据的正确性。
绑定DataGrid
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
}
List<Student> liststudent=new List<Student>();
liststudent.Add(new Student{Name="小张",Age=18});
liststudent.Add(new Student{Name="小张",Age=20});
GridList.ItemsSource = liststudent;
<DataGrid Height="157" x:Name="GridList"/>
【WPF的MVVM DataGrid用法】 https://blog.csdn.net/litao2/article/details/75969595
深入浅出WPF 实例如下:
一:创建简单数据源,并通过 Binding 把它连接到UI元素中。
System.ComponentModel 用于实现组件和控件运行时和设计时行为的类
namespace System.ComponentModel
{
// 摘要:
// 向客户端发出某一属性值已更改的通知。
public interface INotifyPropertyChanged
{
// 摘要:
// 在更改属性值时发生。
event PropertyChangedEventHandler PropertyChanged;
}
}
方法一:
(1)、创建名为Student 类做为数据源,继承 INotifyPropertyChanged(向客户端发出某一属性已更改通知) 接口,
//数据源
public class Student:INotifyPropertyChanged
{
//属性改变
public event PropertyChangedEventHandler PropertyChanged;
private string name;
public string Name
{
get { return name; }
set {
name = value;
if (this.PropertyChanged != null)
{
//属性发生改变后,通知Binding更改UI (Binding Path=**)
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
}
}
}
}
当Name属性的值发生变化时 PropertyChanged 事件就会被激活,Binding接收到这个事件后发现事件的消息告诉它是名为Name的属性发生了值得改变,于是就会通知Binding目标端的UI元素显示新的值。
(2)、UI设计
<TextBox x:Name="textBoxName" BorderBrush="Black" Margin="5"/>
<Button Content="Add Age" Margin="5" Click="Button_Click"/>
(3)、使用Binding 将 数据源和UI连接起来。
数据绑定:
System.Windows.Data.Binding
System.Windows.Data.BindingOperations
Student stu;
public Window1()
{
InitializeComponent();
//准备数据源
stu = new Student();
//准备Binding
Binding binding = new Binding();
binding.Source = stu; //绑定源对象
binding.Path = new PropertyPath("Name");//绑定源对象 属性路径(Name)
//使用Binding 连接数据源 与Binding目标
BindingOperations.SetBinding(this.textBoxName, TextBox.TextProperty, binding);
//BindingOperations.SetBinding(绑定的绑定目标, 绑定的目标属性, 描述绑定的 System.Windows.Data.BindingBase 对象);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
stu.Name += "Name";
}
效果:
方法二:
注意也可以将准备数据源、准备Binding、使用Binding 连接数据源 与Binding目标。三合一操作。
//TextBox基类 FrameworkElement对BindingOperations.SetBinding()方法进行了封装
this.textBoxName.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = stu = new Student()});
//源更改,目标UI也会更改
方法三:
Student4 stu;
public Window30()
{
InitializeComponent();
stu = new Student4();
stu.Name = "aaa";
textBox1.DataContext = stu;
}
<TextBox Name="textBox1" Text="{Binding Path=Name}"/>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:InvokeCommandAction Command="{Binding (DataContext).TreeSelectCommand,
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}" CommandParameter="{Binding Name}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Binding 数据源路径,
RelativeSource(相对数据源)={查找父级,父级类型是Page}
方法四:
<Window x:Class="WpfApplication.Window30"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
Title="Window30" Height="300" Width="300">
<Grid>
<Grid.DataContext>
<local:Student4 Name="aa"/>
</Grid.DataContext>
<TextBox Name="textBox1" Text="{
Binding Path=Name}"/>
</Grid>
</Window>
二:控件间建立关联
1、将TextBox的Text属性 关联 ScrollBar的Value属性
<StackPanel>
<ScrollBar x:Name="SB" Orientation="Horizontal" Height="30"
Minimum="1" Maximum="100" LargeChange="1" SmallChange="1"/>
<TextBox x:Name="textbox1" Height="30" BorderBrush="Blue" BorderThickness="2"
Text="{Binding Value, ElementName=SB}"/>
<!--{Binding 元素属性, ElementName=数据绑定操作源(元素名)}-->
</StackPanel>
c#用法:
//将label的content属性,绑定SB的Vlaue值
textbox1.SetBinding(TextBox.TextProperty, new Binding("Value") {ElementName="SB" });
2、多个控件数据绑定。DataContext
<StackPanel DataContext="{Binding ElementName=SB}">
<ScrollBar x:Name="SB" Orientation="Horizontal" Height="30"
Minimum="1" Maximum="100" LargeChange="1" SmallChange="1"/>
<Label x:Name="labelSBThumb" Height="30" BorderBrush="Blue" BorderThickness="2"
Content="{Binding Path=Value}"/>
<Button Content="Click" Height="200" FontSize="{Binding Path=Value}"/>
</StackPanel>
3、控制Binding的方向及数据更新(TextBox输入值,ScrollBar的值也会更改)
textbox1.SetBinding(TextBox.TextProperty,
new Binding("Value") { ElementName = "SB",
Mode = BindingMode.TwoWay, //数据流动方式为双向
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged //目标属性更改时,立即更新数据源
});
三:Binding 的路径(Path):如何在对象上找数据。
binding支持多级路径,通俗讲就是一路 “点” 下去。
1、一个TextBox显示另一个TextBox输入文本的长度。
<StackPanel>
<TextBox x:Name="textbox1" BorderBrush="Black" Margin="5"/>
<TextBox x:Name="textbox2" BorderBrush="Black" Margin="5" Text="{Binding Path=Text.Length,ElementName=textbox1,Mode=OneWay}"/>
</StackPanel>
注意:Mode=OneWay 无法对“System.String”类型的只读属性“Length”进行 TwoWay 或 OneWayToSource 绑定。
c#代码:
textbox2.SetBinding(TextBox.TextProperty,
new Binding("Text.Length") { Source=this.textbox1,Mode=BindingMode.OneWay});
2、一个TextBox显示另一个TextBox文本的第4个字符。
textbox2.SetBinding(TextBox.TextProperty,
new Binding("Text.[3]") { Source=this.textbox1,Mode=BindingMode.OneWay});
3、将集合或DataView作为Binding的源,把它的默认值当作Path使用
List<string> stringList = new List<string>() { "Litao","Tom","Blog"};
this.textbox1.SetBinding(TextBox.TextProperty,
new Binding("/") { Source = stringList });
this.textbox2.SetBinding(TextBox.TextProperty,
new Binding("/Length") { Source = stringList,Mode=BindingMode.OneWay });
this.textbox3.SetBinding(TextBox.TextProperty,
new Binding("/[2]") { Source = stringList, Mode = BindingMode.OneWay });
结果: