为何BindingContext用{RelativeSource Self}简化失效?对比StaticResource场景
这两种写法的差异核心在于标记扩展的作用场景、返回值类型不同,以及BindingContext与ItemsSource属性的接收要求存在区别:
一、RelativeSource写法失效的本质
{RelativeSource Self}是一个RelativeSource标记扩展,它的作用是给Binding指明源对象的定位规则,但它本身不是目标源对象(即不是Entry控件实例)。
有效写法
BindingContext="{Binding Source={RelativeSource Self}}":
这里是一个完整的Binding表达式:Binding会通过RelativeSource Self的规则定位到当前Entry控件实例,然后把这个实例作为值赋值给BindingContext。此时BindingContext指向Entry自身,后续{Binding Text}自然能找到对应的属性。失效写法
BindingContext="{RelativeSource Self}":
这里直接把RelativeSource标记扩展的返回值(一个RelativeSource类型的对象)赋值给了BindingContext。而RelativeSource对象本身没有Text属性,后续的{Binding Text}找不到目标属性,绑定自然失效。
二、StaticResource简化有效的逻辑
{StaticResource people}是StaticResource标记扩展,它的作用是直接从资源字典中取出名为people的对象实例并返回。
原写法
ItemsSource="{Binding Source={StaticResource people}}":Binding表达式把StaticResource取出的people实例作为Source,由于未指定Path,默认返回Source本身,最终赋值给ItemsSource的就是people实例。简化写法
ItemsSource="{StaticResource people}":
直接把StaticResource取出的people实例赋值给ItemsSource,和原写法的最终效果完全一致——因为ItemsSource需要的就是集合对象实例,不需要经过Binding中转包装。
一句话总结
RelativeSource必须配合Binding的Source属性使用,才能让Binding解析出真正的源对象;直接赋值给BindingContext的是RelativeSource对象,而非目标控件实例。StaticResource本身直接返回目标对象实例,因此可以直接赋值给需要对象实例的属性(如ItemsSource),无需通过Binding中转。
内容的提问来源于stack exchange,提问作者D G

