2014-09-10 58 views
1

到ContentControl中我有3個的DataTemplate在我Window.Resources,強類型的三種不同的類型:綁定一個DataTemplate與ContentTemplateSelector

<DataTemplate x:Key="myTemplateA" DataType="{x:Type local:SampleClassA}"> 
    <Grid> 
     <TextBlock Text="{Binding Path=SampleProperty1}"></TextBlock> 
     <TextBlock Text="{Binding Path=SampleProperty2}"></TextBlock> 
     <TextBlock Text="{Binding Path=SamplePropertyA}"></TextBlock> 
    </Grid> 
</DataTemplate> 

<DataTemplate x:Key="myTemplateB" DataType="{x:Type local:SampleClassB}"> 
    <Grid> 
     <TextBlock Text="{Binding Path=SampleProperty1}"></TextBlock> 
      <TextBlock Text="{Binding Path=SampleProperty2}"></TextBlock> 
      <TextBlock Text="{Binding Path=SamplePropertyB}"></TextBlock> 
     </Grid> 
    </DataTemplate> 

    <DataTemplate x:Key="myTemplateBase" DataType="{x:Type local:SampleClass}"> 
     <Grid> 
      <TextBlock Text="{Binding Path=SampleProperty1}"></TextBlock> 
      <TextBlock Text="{Binding Path=SampleProperty2}"></TextBlock> 
     </Grid> 
    </DataTemplate> 

還有一點DataTemplateSelector:

<local:SampleDataTemplateSelector x:Key="myBindPropertyTemplateSelector" 
    TemplateA="{StaticResource myTemplateA}" 
    TemplateB="{StaticResource myTemplateB}" 
    SampleClassBaseTemplate="{StaticResource myTemplateBase}" /> 

顯然存在類DataTemplateSelector,稱爲​​SampleDataTemplateSelector

Public Class SampleDataTemplateSelector 
    Inherits DataTemplateSelector 

    Public Property TemplateA As DataTemplate 
    Public Property TemplateB As DataTemplate 
    Public Property SampleClassBaseTemplate As DataTemplate 

    Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate 

     If item Is Nothing Then Return SampleClassBaseTemplate 

     If item.GetType.Equals(GetType(SampleClassA)) Then 
      Return TemplateA 
     End If 

     If item.GetType.Equals(GetType(SampleClassB)) Then 
      Return TemplateB 
     End If 

     Return SampleClassBaseTemplate 
    End Function 

End Class 

DataTemplateSelector必須區分3個簡單的類:SampleClass和2個派生類SampleClassA,SampleClassB。

Public Class SampleClass 
    Public Property SampleProperty1 As String = "Class SampleClass Property1" 
    Public Property SampleProperty2 As String = "Class SampleClass Property2" 
End Class 

Public Class SampleClassA 
    Inherits SampleClass 
    Public Property SamplePropertyA As String = "Class SampleClassA" 
End Class 

Public Class SampleClassB 
    Inherits SampleClass 
    Public Property SamplePropertyB As String = "Class SampleClassB" 
End Class 

在我的窗前,XAML中ContentControl中設置類似如下:

<ContentControl Content="{Binding BindProperty}" ContentTemplateSelector="{StaticResource myBindPropertyTemplateSelector}" /> 

凡BindProperty是隱藏窗口代碼中定義的屬性:

Dim myBindProperty As SampleClass 
Public ReadOnly Property BindProperty As SampleClass 
    Get 
     Return myBindProperty 
    End Get 
End Property 

畢竟,在我的窗口查看事件有BindProperty初始化

Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded 
    myBindProperty = New SampleClassA() 
End Sub 

沒有編譯錯誤。在執行過程中,SampleDataTemplateSelector的SelectTemplate例程中的item參數始終爲Nothing,因此它不能選擇正確的模板...並不顯示任何內容。我做錯了什麼?

+0

你設置DataContext的地方?在C#中,像這樣:this.DataContext = this; – 2014-09-10 17:06:57

+0

我嘗試在xaml(DataContext =「{Binding local:BindProperty}」)中設置DataContext,並且在代碼後面(myContentControl.DataContext = myBindProperty)中,但沒有任何更改。 – 2014-09-10 17:19:14

+0

Try,myContentControl.DataContext = this(the window)。 myBindProperty不是一個屬性,所以我不認爲你可以使用它(它必須是一個屬性而不是成員變量)。如果你設置了myContentControl.DataContext = BindProperty,那麼你需要將xaml改爲Content =「{Binding}」,因爲上下文已經是BindProperty了。 – 2014-09-10 17:24:59

回答

3

我重新創建了您的項目,如果您將DataContext = Me添加到Window_Loaded,它會工作。我改變了你的模板來使用StackPanel而不是Grid(所以文本塊沒有相互重疊)。 這裏是一個完整的,工作版本:

enter image description here

MainWindow.xaml

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication20" 
    Loaded="Window_Loaded" 
    Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <DataTemplate x:Key="myTemplateA" DataType="{x:Type local:SampleClassA}"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path=SampleProperty1}"></TextBlock> 
       <TextBlock Text="{Binding Path=SampleProperty2}"></TextBlock> 
       <TextBlock Text="{Binding Path=SamplePropertyA}"></TextBlock> 
      </StackPanel> 
     </DataTemplate> 

     <DataTemplate x:Key="myTemplateB" DataType="{x:Type local:SampleClassB}"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path=SampleProperty1}"></TextBlock> 
       <TextBlock Text="{Binding Path=SampleProperty2}"></TextBlock> 
       <TextBlock Text="{Binding Path=SamplePropertyB}"></TextBlock> 
      </StackPanel> 
     </DataTemplate> 

     <DataTemplate x:Key="myTemplateBase" DataType="{x:Type local:SampleClass}"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path=SampleProperty1}"></TextBlock> 
       <TextBlock Text="{Binding Path=SampleProperty2}"></TextBlock> 
      </StackPanel> 
     </DataTemplate> 

     <local:SampleDataTemplateSelector x:Key="myBindPropertyTemplateSelector" 
      TemplateA="{StaticResource myTemplateA}" 
      TemplateB="{StaticResource myTemplateB}" 
      SampleClassBaseTemplate="{StaticResource myTemplateBase}" /> 
    </Window.Resources> 
    <Grid> 
     <ContentControl Content="{Binding BindProperty}" ContentTemplateSelector="{StaticResource myBindPropertyTemplateSelector}" /> 
    </Grid> 
</Window> 

MainWindow.xaml.vb

Class MainWindow 
    Dim myBindProperty As SampleClass 
    Public ReadOnly Property BindProperty As SampleClass 
     Get 
      Return myBindProperty 
     End Get 
    End Property 

    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) 
     myBindProperty = New SampleClassA() 
     DataContext = Me 
    End Sub 
End Class 

Public Class SampleClass 
    Public Property SampleProperty1 As String = "Class SampleClass Property1" 
    Public Property SampleProperty2 As String = "Class SampleClass Property2" 
End Class 

Public Class SampleClassA 
    Inherits SampleClass 
    Public Property SamplePropertyA As String = "Class SampleClassA" 
End Class 

Public Class SampleClassB 
    Inherits SampleClass 
    Public Property SamplePropertyB As String = "Class SampleClassB" 
End Class 

Public Class SampleDataTemplateSelector 
    Inherits DataTemplateSelector 

    Public Property TemplateA As DataTemplate 
    Public Property TemplateB As DataTemplate 
    Public Property SampleClassBaseTemplate As DataTemplate 

    Public Overrides Function SelectTemplate(item As Object, container As DependencyObject) As DataTemplate 

     If item Is Nothing Then Return SampleClassBaseTemplate 

     If item.GetType.Equals(GetType(SampleClassA)) Then 
      Return TemplateA 
     End If 

     If item.GetType.Equals(GetType(SampleClassB)) Then 
      Return TemplateB 
     End If 

     Return SampleClassBaseTemplate 
    End Function 

End Class 
+0

嗨,謝謝你的答案,JH ... 我不明白,代碼是一樣的...唯一的區別是在命名空間上: xmlns:local =「clr-namespace:Cacatua; assembly = 「 我所有的項目文件都在」Cacatua「命名空間中,並位於同一個程序集中。我的程序集沒有Root名稱空間。 – 2014-09-11 08:25:31

+0

奇怪的是在調試時:如果我在SelectTemplate中放置一個斷點,Item沒有任何東西,因爲它在myLindProperty初始化的Window_Loaded事件之前調用DataTemplateSelector。我嘗試在InitializeComponent調用之前初始化構造函數上的BindProperty,但SelectTemplate中的項目沒有任何內容(所以我看不到任何東西)。 – 2014-09-11 08:26:04

+0

好吧,我的錯,代碼工作!謝謝J.H.!如果你來意大利,我會給你喝一杯! 非常感謝! – 2014-09-11 09:06:14