2010-07-21 56 views
13

我有一類是這樣的:遞歸DataTemplates可能嗎?

public class Section 
{ 
    private IEnumerable<Section> sections; 
    private IEnumerable<KeyValuePair<string, string>> attributes 

    public string Name {get;set;} 
    public IEnumerable<Section> Sections 
    { 
     get {return sections;} 
    } 
    public IEnumerable<KeyValuePair<string, string>> Attributes 
    { 
     get {return attributes;} 
    } 

    public Section(...) 
    { 
     //constructor logic 
    } 
} 

這是包含在另一個類,讓叫它OtherClass爲了論證的緣故,環繞它和WPF使用在ObjectDataProvider的。

如您所見,Section的一個實例可以包含許多其他Section實例。

有沒有辦法在XAML中創建一個處理此遞歸的模板?

這是我到目前爲止有:

<UserControl x:Class="OtherClassEditor" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:OtherClassNS="clr-namespace:NameSpace" 
    Height="300" Width="300"> 
    <UserControl.Resources> 
     <ObjectDataProvider ObjectType="{x:Type OtherClassNS:OtherClass}" x:Key="ViewModel" /> 
     <DataTemplate x:Key="listViewAttr"> 
      <WrapPanel> 
       <TextBlock Text="{Binding Path=Key}"></TextBlock><TextBlock Margin="0,0,4,0">: </TextBlock> 
       <TextBlock Text="{Binding Path=Value}"></TextBlock> 
      </WrapPanel> 
     </DataTemplate> 
     <DataTemplate x:Key="listViewSection"> 
      <StackPanel> 
       <WrapPanel Margin="0,0,0,8"> 
        <TextBlock Margin="0,0,4,0">Section:</TextBlock> 
        <TextBlock Text="{Binding Path=Name}"/> 
       </WrapPanel> 
      </StackPanel> 
     </DataTemplate> 
     <DataTemplate x:Key="listViewData"> 
      <StackPanel> 
       <WrapPanel Margin="0,0,0,8"> 
        <TextBlock Margin="0,0,4,0">Section: </TextBlock> 
        <TextBlock Text="{Binding Path=Name}"/> 
        <ListView DataContext="{Binding Path=Sections}" ItemTemplate="{StaticResource listViewSection}" ItemsSource="{Binding Sections}"> 
        </ListView> 
        <ListView DataContext="{Binding Path=Attributes}" ItemsSource="{Binding Attributes}" ItemTemplate="{StaticResource listViewAttr}"> 

        </ListView> 
       </WrapPanel> 
      </StackPanel>  
     </DataTemplate> 
    </UserControl.Resources> 
    <Grid> 
     <ListView DataContext="{StaticResource ViewModel}" ItemTemplate="{StaticResource listViewData}" ItemsSource="{Binding Sections}"> 
     </ListView> 
    </Grid> 
</UserControl> 

但我不能讓遞歸,作爲DataTemplate只能引用一個是之前宣佈。

這可以在XAML中完成嗎?如果是這樣,怎麼樣?這是我需要在代碼後面做的事嗎?

DataTemplates是否應該走?是否有更好的方式來顯示和編輯這些數據?

+3

如果您使用DynamicResource而不是StaticResource,這是否工作?如果它有效,它會很有趣,但如果模板導致無限遞歸,我會討厭看看會發生什麼。 – 2010-07-21 14:01:35

+0

我沒有想到這個!它確實有效,但我喜歡'HierarchicalDataTemplate'的外觀。它似乎更適合用途。 – 2010-07-21 14:32:12

回答

2

也許我誤解了你的情況,但是HierarchicalDataTemplate你在找什麼?

+0

感謝您的提示,我現在正在閱讀它。 – 2010-07-21 14:10:49

+0

HierarchicalDataTemplate僅適用於TreeView和MenuItem。我不知道爲什麼這是被接受的答案。 – 2017-01-09 17:54:02

22

如果有人需要看看如何做到這一點,而無需使用HierarchicalDataTemplate

<UserControl x:Class="OtherClassEditor" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:OtherClassNS="clr-namespace:NameSpace" 
    Height="300" Width="300"> 
    <UserControl.Resources> 
     <ObjectDataProvider ObjectType="{x:Type OtherClassNS:OtherClass}" x:Key="ViewModel" /> 
     <DataTemplate x:Key="listViewAttr"> 
      <WrapPanel> 
       <TextBlock Text="{Binding Path=Key}"></TextBlock> 
       <TextBlock Margin="0,0,4,0">: </TextBlock> 
       <TextBlock Text="{Binding Path=Value}"></TextBlock> 
      </WrapPanel> 
     </DataTemplate> 
     <DataTemplate x:Key="listViewData"> 
      <StackPanel> 
       <WrapPanel Margin="0,0,0,8"> 
        <TextBlock Margin="0,0,4,0">Section: </TextBlock> 
        <TextBlock Text="{Binding Path=Name}"/> 
       </WrapPanel> 
       <ListView ItemTemplate="{DynamicResource listViewData}" ItemsSource="{Binding Sections}" /> 
       <ListView ItemsSource="{Binding Attributes}" ItemTemplate="{StaticResource listViewAttr}" /> 
      </StackPanel>  
     </DataTemplate> 
    </UserControl.Resources> 
    <Grid> 
     <ListView DataContext="{StaticResource ViewModel}" ItemTemplate="{DynamicResource listViewData}" ItemsSource="{Binding Sections}"> 
     </ListView> 
    </Grid> 
</UserControl> 

這讓我基本上我想要什麼。

主要變化是Dan Bryant建議的:將ItemTemplate更改爲對遞歸對象(Section)使用Dynamic而不是靜態資源。