WPF-StyleTemplate 内的{Binding}
{Binding} 不等于 什么也不绑定,真实含义为绑定到当前DataContext本身。{Binding} = {Binding Path=.}
一、为什么在 Style / Template 里特别常见 {Binding}?
因为在 Style / ControlTemplate 里:
- 通常 不知道具体绑定路径
- 不应该写死 ViewModel 属性名
- 关心:“当前对象代表的那份数据”
二、经典的使用场景:DataTemplate
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>这是什么意思?
假设:
ItemsSource = new List<string> { "张三", "李四" };那么:
- 每一项的 DataContext 是” 张三“,”李四“
- {Binding} = 绑定到当前那一项本身
- TextBlock.Text = ”张三“
误区:实际显示为两个TextBlock, 分别为TextBlock.Text = " 张三",TextBlock.Text = " 李四"。DataTemplate不是一个静态的占位符,而是一个“生产车间**”。** 它根据你的数据源数量,批量生产出互不干扰的 UI 零件。每一个零件(TextBlock)都只盯着分配给它自己的那块数据(Item)。
三、{Binding} 在 Style 内常见的原因
关键:Style/Template是”通用的“,它不知道:”你的ViewModel是谁“,”属性叫什么“,”数据结构长什么样“
错误写法(Style/Template内):
Text="{Binding UserName}"可以这样写:
Text="{Binding}" 或 Content="{Binding}"四、一个常见的例子
ListBox默认样式内部(简化版)
<ContentPresenter
Content="{Binding}"
ContentTemplate="{TemplateBinding ContentTemplate}"为什么是{Binding}?
因为:ListBoxItem的DataContext = 当前数据线。这个数据项可能是:string/User/Order/任意对象。ContentPresenter只负责”把这条数据展示出来“,至于怎么展示由 DataTemplate 决定。
五、{Binding}和{TemplateBinding}的区别
{Binding}
| 绑定目标 | 说明 |
|---|---|
| DataContext | 当前逻辑数据 |
| 常见位置 | DataTemplate/Style |
| 场景 | 绑定数据对象 |
{TemplateBinding} — Background="{TemplateBinding Background}"
| 绑定目标 | 说明 |
|---|---|
| TemplatedParent | 控件自身 |
| 常见位置 | ControlTemplate |
| 场景 | 控件属性转发 |
六、为什么Style里Binding"写得很奇怪"?
因为它们绑定的对象不同:
| 写法 | 事件绑定 |
|---|---|
| {Binding} | 当前DataContext |
| {Binding Path=Name} | DataContext.Name |
| {Binding RelativeSource=TemplatedParent} | 控件自己 |
| {TemplateBinding} | 控件自己( 更快) |
七、常见写法
<Setter Property="Content" Value="{Binding}"含义:这个控件的Content就等于当前DataContext
八、对Setter内Binding产生误区的原因
1.Setter不在逻辑树
2.没有ElementName
3.没有明确的DataContext
4.Binding只能在应用到控件那一刻才生效
所以{Binding}的真正意思是:”将来被应用到哪个控件,就绑定它当时的DataContext“
总结:
{Binding}就像:”使用当前内力“,而不是”使用张三的内力/李四的内力“
在秘籍(Style)里你只能写:”用当前修炼者的内力“ 不能写”用张三/李四的内力“
{Binding}等价于{Binding Path=.};它绑定的是当前DataContext本身;在Style/Template里非常常见;因为Style必须是” 通用的“;Setter里的Binding在”应用时“才解析;
看不懂{Binding}时,先思考”此时DataContext“是谁?
Binding = (绑定目标) + (绑定路径)
对于奇怪的{Binding},搞清两个问题: 1.绑定目标是谁 2.DataContext是谁