一、 绑定表达式
数据绑定是将两个数据/信息源绑定在一起并保持数据同步的通用技术。
<TextBox x:Name="sourceTBox" Text="hello world!" />
<TextBlock x:Name="tb" Text="{Binding ElementName=sourceTBox,Path=Text,Mode=Default}" />
绑定关系由四个方面组成:
1.绑定目标 指包含绑定表达式的控件元素 如:TextBlock
2.绑定目标属性 控件的属性设置了绑定表达式,这个属性就是目标属性 如:TextBlock的Text属性
3.绑定源 绑定表达式中 ElementName 属性所指向的元素
4.绑定源属性 绑定源的属性
二、绑定模式
当设置 Binding.Mode 属性时。WPF 允许使用 5 个 system.windows.data.BindingMode 枚举值中的任何一个。代码如下,其中的 Mode=TwoWay 就是设置绑定模式
| 枚举名称 | 说明 |
|---|---|
| OneWay | 当源属性变化时更新目标属性 |
| TwoWay | 当源属性变化时更新目标属性 ,当目标属性 变化时更新源属性 |
| OneTime | 最初设定源属性时更新目标属性,后期的变化都被忽略 ,如果知道源属性不会变化,可以使用这种模式,降低开销 |
| OneWayToSource | 与OneWay 类似,但方向相反,当目标属性变化时更新源属性,有点向后传递,但目标属性永远不会被更新 |
| Default | 此类绑定依赖于目标属性,即可以是双向(对于用户可以设置的属性,如TextBlock.Text,) 也可以是单向,除非明确指明一种模式,否则都采用此种模式 |
下图可以帮助我们更好的理解数据绑定:
三、绑定更新
<TextBlock x:Name="tb" Text="{Binding Text,ElementName=sourceTBox,Mode=TwoWay,UpdateSourceTrigger=Default}" />
关键属性:UpdateSourceTrigger,枚举值:
| 名称 | 说明 |
|---|---|
| PropertyChanged | 属性发生变化时更新 |
| LostFous | 失去焦点时更新 |
| Explicit | 调用 BindingExpress.UpdateSource()时更新 |
| Defeat | 根据属性的元数据确定更新行为(FrameworkPropertyMetadata.DefaultUpdateSourceTriggere) 大多数默认行为 是PropertyChanged 但TextBox.Text 默认行为是 LostFocus |
四、延迟绑定
<TextBlock x:Name="tb" Text="{Binding Text,ElementName=sourceTBox,Mode=TwoWay,Delay=500}" />
关键属性:Delay
作用 :避免过分频繁的触发操作,导致频繁更新UI。
使用 Binding 对像的 Delay 属性。等待数毫秒之后再提交更新。
五、RelativeSource 相对绑定
<TextBlock Text="{Binding Title,RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType={x:Type Window}}}" />
可以使用RelativeSource 属性将元素绑定 自身 或 父元素。
-
绑定到父元素 Mode=FindAncestor
-
绑定到自身 Mode="Self"
-
绑定到列表数据中的前一个数据项 Mode="PreviousData"
-
绑定到应用模板元素 Mode="TemplatedParent"
六、DataContent属性
<TextBlock Text="{Binding Version}" />
//Window 对像DataContent 属性引用对像 SystemVersion
public class SystemVersion{
public int Code { get; set; }
public String Version { get; set; }
}
//设置 Window 对像DataContent 属性
this.DataContext = new SystemVersion()
{
Code = 103,
Version = "V1.0.3"
};
Wpf就从当前元素开始在元素树中向上查找。检查每一个元素的DataContent属性,并使用 第一个非空的DataContent 属性 所引用的对像的 Version 属性。
如果 TextBlock的Text 直到 Window 对像DataContent 属性引用一个对像不为空,TextBlock的Text 就绑定到 Window 对像DataContent 属性引用对像的 Version 属性上。
七、绑定转换
对于简单的数据格式化,可以通过StringFormat来处理
<StackPanel x:Name="simpleconvert">
<TextBlock Text="{Binding Date,StringFormat=yyyy-MM-dd}" />
<TextBlock Text="{Binding Price,StringFormat=f2}" />
</StackPanel>
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.simpleconvert.DataContext = new SimpleDataConvert();
}
}
class SimpleDataConvert
{
public DateTime Date { get; set; } = DateTime.Now;
public float Price { get; set; } = 100.123456f;
}
无法通过StingFormat处理的数据,则需要使用Converter属性来处理,即转换器,
<Window x:Class="WpfDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfDemo"
xmlns:utils="clr-namespace:WpfDemo.Utils"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<utils:DataConverter x:Key="dataconvert" />
</Window.Resources>
<StackPanel Margin="100,200,100,100">
<StackPanel x:Name="simpleconvert">
<TextBox Text="{Binding Price,Converter={StaticResource dataconvert}}" />
</StackPanel>
</StackPanel>
</Window>
namespace WpfDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.simpleconvert.DataContext = new SimpleDataConvert();
}
}
class SimpleDataConvert
{
public DateTime Date { get; set; } = DateTime.Now;
public float Price { get; set; } = 100.12f;
}
}
namespace WpfDemo.Utils
{
public class DataConverter : IValueConverter
{
/// <summary>
/// 数据源转界面显示
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
return "$" + value;
}
else
{
return value;
}
}
/// <summary>
/// 界面显示转数据源
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value.ToString().StartsWith("$"))
{
return value.ToString().Trim('$');
}
else
{
return value;
}
}
}
}