You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 18:55:55