如何将WPF自定义控件的ItemTemplate绑定到DataTemplateSelector的CLR属性?
解决方案
方案一:将Template2改为依赖属性
你之前的认知有误——DataTemplateSelector继承自Freezable,而Freezable本身就是DependencyObject的子类,所以完全可以给Template2定义依赖属性,这样就能支持绑定了。
修改你的TestTemplateSelector类:
Public Class TestTemplateSelector Inherits DataTemplateSelector ' Template1 可保留普通属性,也可改为依赖属性,按需选择 Public Property Template1 As DataTemplate ' Template2 定义为依赖属性 Public Shared ReadOnly Template2Property As DependencyProperty = DependencyProperty.Register("Template2", GetType(DataTemplate), GetType(TestTemplateSelector)) Public Property Template2 As DataTemplate Get Return CType(GetValue(Template2Property), DataTemplate) End Get Set(value As DataTemplate) SetValue(Template2Property, value) End Set End Property Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate ' 你的条件判断逻辑 If condition Then Return Me.Template1 Else Return Me.Template2 End If End Function End Class
之后XAML里的绑定写法即可正常工作:
<DataTemplate x:Key="Template1"> <TextBlock Text="Template 1" /> </DataTemplate> <local:TestTemplateSelector x:Name="TestTemplateSelector" Template1="{StaticResource Template1}" Template2="{Binding ItemTemplate, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TestControl}}" />
方案二:在SelectTemplate方法中直接获取父控件的ItemTemplate
如果不想修改属性类型,也可以在模板选择器的逻辑里,通过传入的container参数向上查找你的自定义控件,直接读取它的ItemTemplate属性,无需在XAML中绑定Template2。
修改TestTemplateSelector类:
Public Class TestTemplateSelector Inherits DataTemplateSelector Public Property Template1 As DataTemplate Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate ' 向上查找TestControl实例 Dim parentControl As TestControl = FindParent(Of TestControl)(container) ' 你的条件判断逻辑 If condition Then Return Me.Template1 Else ' 返回父控件的ItemTemplate Return parentControl?.ItemTemplate End If End Function ' 通用的父元素查找方法 Private Function FindParent(Of T As DependencyObject)(child As DependencyObject) As T Dim parent = VisualTreeHelper.GetParent(child) If parent Is Nothing Then Return Nothing End If If TypeOf parent Is T Then Return CType(parent, T) Else Return FindParent(Of T)(parent) End If End Function End Class
对应的XAML可简化为:
<DataTemplate x:Key="Template1"> <TextBlock Text="Template 1" /> </DataTemplate> <local:TestTemplateSelector x:Name="TestTemplateSelector" Template1="{StaticResource Template1}" />
两种方案均可满足需求,可根据自身代码习惯选择。
内容的提问来源于stack exchange,提问作者Nostromo
相关产品推荐
相关产品推荐

