以下案例使用的统一的数据源:
public class Data
{
public string Value { get; set; } = "123";
public int IntValue { get; set; } = 100;
public float FloatValue { get; set; } = 0.114f;
public DateTime DateTimeValue { get; set; } = DateTime.Now;
public int CodeValue { get; set; } = 64; // '@'
}
Mode:绑定对象的属性
TwoWay:绑定的双方,数值可以相互传递
OneWay:绑定后,数据从源到目标
OneTime:绑定的双方,在初始化的时候,数据同步一次
OneWayToSource:单向绑定,数据从普通目标到源 与 OneWay 相反
Default:默认模式,没有Mode属性一样,默认是什么形式就是什么形式
<TextBlock Text="{Binding Value,Mode=TwoWay}"/>
<!---->
<TextBox Text="{Binding Value,Mode=OneTime}"/>
<TextBox Text="{Binding Value,Mode=Default}"/>
<TextBox Text="{Binding Value,Mode=OneWayToSource}"/>
注意:
源数据属性只读的时候,不可以单独使用Binding
如果属性只读,使用TextBox Binding报错:
原因:TextBlock只做显示,TextBox可以做编辑(页面输入的时候,信息会回写,写到Value属性中去)
这里的问题与属性问题无关
如果不写Mode的时候,是否双向绑定还是根据默认的来设置的
TextBox的Text属性推送给资源的时机是控件失去焦点
UpdateSourceTrigger:更新源触发器
Default:控件默认
PropertyChanged:属性修改时触发
LostFocus:失去焦点 更新源
Explicit:明确的告诉进行更新
XAML代码:
<Button Content="Button" Click="Button_Click" />
<TextBox Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=Default}" />
<TextBox Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=Explicit}" Name='tb'/>
C#代码:这个C#代码是处理Explicit事件的
private void Button_Click(object sender, RoutedEventArgs e)
{
// 获取对应控件属性的绑定表达式
BindingExpression bindingExpression = tb.GetBindingExpression(TextBox.TextProperty);
// 指定更新源
bindingExpression.UpdateSource();
}
Delay:延迟更新
属性变化的时候做什么逻辑:
UpdataSource 的时候,每次变化都会触发Set,如果Set有逻辑, 则跟不上
希望每次输入都更新,而且不需要失去焦点,又不希望每个字符都更新
可以让更新的时机稍等下 Delay
Text 属性被连续更新后多少毫秒,如果连续输入不会触发,输入完开始计时
<!--这里更新的时候需要失去焦点,Delay无效,不会等待2000-->
<TextBox Text="{Binding Value,Mode=TwoWay,Delay=2000}" />
<!--实时同步更新源的时候,可以等待-->
<TextBox Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,Delay=2000}" />
注意:只有使用UpdateSourceTrigger=PropertyChanged的时候才能使用延迟。
StringFormat:
货币格式
<TextBlock Text="{Binding Price, StringFormat={}{0:C}}" /> // $123.46
货币格式(1位小数)
<TextBox Text="{Binding Price, StringFormat={}{0:C1}}" /> // $123.5
<!--ConverterCulture=ZH-CN 中文钱符号-->
<TextBlock Text="{Binding Price,StringFormat={}{0:C1},ConverterCulture=ZH-CN}" />// ¥123.5
前文字
<TextBox Text="{Binding Price, StringFormat=单价:{0:C}}" /> //单价:$123.46
后文字
<TextBox Text="{Binding Price, StringFormat={}{0}元}" /> // 123.45678元
固定的位数,位数不能少于未格式化前(仅支持整型)
<TextBox Text="{Binding Count, StringFormat={}{0:D6}}" /> // 086723
指定小数点后的位数
<TextBox Text="{Binding Total, StringFormat={}{0:F4}}" /> // 28768234.9329
用分号隔开的数字,并指定小数点后的位数
<TextBox Text="{Binding Total, StringFormat={}{0:N3}}" /> // 28,768,234.933
格式化百分比
<TextBox Text="{Binding Persent, StringFormat={}{0:P1}}" /> // 78.9 %
占位符
<TextBox Text="{Binding Price, StringFormat={}{0:0000.00}}" /> // 0123.46
<TextBox Text="{Binding Price, StringFormat={}{0:####.##}}" /> // 123.46
日期和时间
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:d}}" /> // 5/4/2015
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:D}}" /> // Monday, May 04, 2015
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:f}}" /> // Monday, May 04, 2015 5:46 PM
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:F}}" /> // Monday, May 04, 2015 5:46:56 PM
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:g}}" /> // 5/4/2015 5:46 PM
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:G}}" /> // 5/4/2015 5:46:56 PM
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:m}}" /> // May 04
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:M}}" /> // May 04
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:t}}" /> // 5:46 PM
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:T}}" /> // 5:46:56 PM
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:yyyy年MM月dd日}}" /> // 2015年05月04日
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:yyyy-MM-dd}}" /> // 2015-05-04
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:yyyy-MM-dd HH:mm}}" /> // 2015-05-04 17:46
<TextBox Text="{Binding DateTimeNow, StringFormat={}{0:yyyy-MM-dd HH:mm:ss}}" /> // 2015-05-04 17:46:56
多重绑定
// 姓名:AAbb
<TextBox.Text>
<MultiBinding StringFormat="姓名:{0}{1}">
<Binding Path="FristName" />
<Binding Path="LastName" />
</MultiBinding>
</TextBox.Text>
多重绑定中的特殊字符
<TextBox.Text>
<MultiBinding StringFormat="姓名:{0}	{1}">
<Binding Path="FristName" />
<Binding Path="LastName" />
</MultiBinding>
</TextBox.Text>
<!--
\a  BEL
\b  BS - Backspace
\f  FF - Formfeed
\n 
 LF, NL - Linefeed, New Line
\r 
 CR - Carriage return
\t 	 HT - Tab, Horizontal Tabelator
\v  VT - Vertical Tabelator
-->
其他写法: <!--{}{} 和 \{\} 一样-->
<TextBlock Text="{Binding Price, StringFormat={}{0:C}}" /> // $123.46
<TextBlock Text="{Binding Price, StringFormat=\{0:C\}}" /> // $123.46
Converter:转换器
xaml:
<StackPanel>
<StackPanel.Resources>
<local:CharConvert x:Key="cc" />
</StackPanel.Resources>
<!--只有继承MarkupExtension才可以使用{}处理-->
<TextBlock Text="{Binding CodeValue,Converter={local:CharConvert}}"/>
<!--简写方式 需要提前定义资源-->
<TextBlock Text="{Binding CodeValue,Converter = {StaticResource cc}}" />
<!--完整方式 可以不用定义资源-->
<TextBlock>
<TextBlock.Text>
<Binding Path="CodeValue">
<Binding.Converter>
<local:CharConvert/>
</Binding.Converter>
</Binding>
</TextBlock.Text>
</TextBlock>
<TextBox Text="{Binding CodeValue,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource cc}}" />
</StackPanel>
转换器代码:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Markup;
namespace XH.BindingLesson.BindingProperties
{
// MarkupExtension 不是必须继承的 主要目的是希望CharConvert可以以{}的形式 在xaml中实例化
// 比如{local:CharConvert}
// 如果没有继承MarkupExtension 的情况下,xaml中以资源或标签对象的方式进行引用
public class CharConvert : MarkupExtension, 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)
{
// 源数据
return (char)int.Parse(value.ToString());
}
/// <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)
{
return (int)value.ToString()[0];
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
显示:CodeValue = 64 显示为@ 没问题:
注意:
MarkupExtension 不是必须继承的 主要目的是希望CharConvert可以以{}的形式 在xaml中实例化
比如{local:CharConvert}
如果没有继承MarkupExtension 的情况下,xaml中以资源或标签对象的方式进行引用
ConverterParemeter:转换参数
使用说明:可以在值转换的时候传入一个参数 Object类型
XAML中:
<StackPanel>
<TextBlock Text="{Binding CodeValue,Converter={StaticResource cc},ConverterParameter=0}" />
<TextBlock Text="{Binding CodeValue,Converter={StaticResource cc},ConverterParameter=2}" />
<TextBlock Text="{Binding CodeValue,Converter={StaticResource cc},ConverterParameter=4}" />
</StackPanel>
C#中:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Markup;
namespace XH.BindingLesson.BindingProperties
{
public class CharConvert : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// 源数据
return (char)int.Parse((int.Parse(value.ToString()) + int.Parse(parameter == null ? "0" : parameter.ToString())).ToString());
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value.ToString()[0];
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
每次触发转换的时候,都会传一个parameter值给两个方法中。
FallbackValue:绑定失败值
FailbackValue无法绑定的时候(绑定错误的时候),显示个默认值
1、找不到数据源
2、Path路径无效
<TextBlock Text="{Binding ElementName=cb,Path=aaa,FallbackValue = 绑定失败 }" />
显示:
TargetNullValue:数据源为Null显示
TargetNullValue 数据源属性的值为null的时候,目标属性中需要显示的信息
<TextBlock Text="{Binding ElementName=cb,Path=IsChecked,FallbackValue = 绑定失败 ,TargetNullValue= 空值}" />
显示结果: