0

我正在尝试使用 HierarchicalDataTemplate 递归地创建包含项目的扩展器,但是当我使用 HierarchicalDataTemplate 时,我只能显示第一级项目。

如果您需要任何信息,请告诉我。

下面是我手写时 xaml 的样子:

<GroupBox Header="SectionHeader">
    <StackPanel >
        <Expander VerticalAlignment="Top" Header="SubSectionHeader">
            <StackPanel>
                <Expander VerticalAlignment="Top" Header="SubSectionHeader" Margin="10,0,0,0">
                    <StackPanel>
                        etc......
                    </StackPanel>
                </Expander>
         </Expander>
    </StackPanel>
</GroupBox>

这是我到目前为止所拥有的。

xml:

<ItemsControl Name="lstMain" ItemsSource="{Binding Sections}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <GroupBox Header="{Binding Section.SectionName}">
                <ItemsControl ItemsSource="{Binding SubSections}" ItemTemplate="{StaticResource BinderTemplate}" />
            </GroupBox>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

<HierarchicalDataTemplate x:Key="BinderTemplate" ItemsSource="{Binding Path=SubSections}" DataType="{x:Type local:SubSectionViewModel}">
    <StackPanel>
        <Expander Header="{Binding SubSection.SubSectionName}"/>
    </StackPanel>
</HierarchicalDataTemplate>

数据类:

class TopViewModel
{
    ObservableCollection<SectionViewModel> _sections = new ObservableCollection<SectionViewModel>();

    public ObservableCollection<SectionViewModel> Sections
    {
        get
        {
            return _sections;
        }
        set
        {
            _sections = value;
        }
    }
}

public class SectionViewModel
{
    ObservableCollection<MaterialViewModel> _materials = new ObservableCollection<MaterialViewModel>();
    ObservableCollection<SubSectionViewModel> _subSections = new ObservableCollection<SubSectionViewModel>();
    Section _section;

    public Section Section
    {
        get
        {
            return _section;
        }
        set
        {
            _section = value;
        }
    }

    public string MaterialName
    {
        get { return Section.SectionName; }
        set { Section.SectionName = value; }
    }

    public ObservableCollection<MaterialViewModel> Materials
    {
        get
        {
            return _materials;
        }
        set
        {
            _materials = value;
        }
    }

    public ObservableCollection<SubSectionViewModel> SubSections
    {
        get
        {
            return _subSections;
        }
        set
        {
            _subSections = value;
        }
    }
}

public class SubSectionViewModel
{
    ObservableCollection<MaterialViewModel> _materials = new ObservableCollection<MaterialViewModel>();
    ObservableCollection<SubSectionViewModel> _subSections = new ObservableCollection<SubSectionViewModel>();
    SubSection _subSection;

    public ObservableCollection<MaterialViewModel> Materials
    {
        get
        {
            return _materials;
        }
        set
        {
            _materials = value;
        }
    }

    public ObservableCollection<SubSectionViewModel> SubSections
    {
        get
        {
            return _subSections;
        }
        set
        {
            _subSections = value;
        }
    }

    public SubSection SubSection
    {
        get
        {
            return _subSection;
        }
        set
        {
            _subSection = value;
        }
    }
}
4

3 回答 3

3

您在您的HierarchicalDataTemplate- 如何呈现子元素中缺少一个关键位:

<HierarchicalDataTemplate x:Key="BinderTemplate" 
    ItemsSource="{Binding Path=SubSections}" 
    DataType="{x:Type local:SubSectionViewModel}">
    <StackPanel>
        <Expander Header="{Binding SubSection.SubSectionName}">
            <ItemsControl Margin="5,0,0,0" 
                      ItemsSource="{Binding SubSections}" 
                      ItemTemplate="{DynamicResource BinderTemplate}"/>
        </Expander>
    </StackPanel>
</HierarchicalDataTemplate>

编辑:不要窃取@BDE 的风头,但他/她对使用的基本正确DataType- 但这是您“简化”上述 XAML 的方式:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:WpfApplication1" 
        Title="Window1" Height="300" Width="300">
    <Window.Resources>
         <!-- normal template for sections -->
         <DataTemplate DataType="{x:Type local:SectionViewModel}">
            <GroupBox Header="{Binding Section.SectionName}">
                <ItemsControl ItemsSource="{Binding SubSections}"/>
            </GroupBox>
         </DataTemplate>
         <!-- hierarchical template for subsections -->
         <HierarchicalDataTemplate 
              DataType="{x:Type local:SubSectionViewModel}">
           <StackPanel>
               <Expander Header="{Binding SubSection.SubSectionName}">
                   <ItemsControl Margin="5,0,0,0" 
                         ItemsSource="{Binding SubSections}"/>
               </Expander>
           </StackPanel>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <!-- 
           no need to specify ItemTemplate if WPF can suss out all the item types 
         -->
        <ItemsControl Name="lstMain" ItemsSource="{Binding Sections}"/>
    </Grid>
</Window>
于 2013-01-03T16:49:44.433 回答
1

另一种方法是在您的数据模板HierarchicalDataTemplate中添加一个,并在那里绑定。ItemsControlExpanderItemsSource

此外,由于您DataType在数据模板定义中指定了 ,因此您不必直接ItemTemplate为您的 toplevel 设置键名ItemsControl

如果你像这样修改你的 XAML,它可能会做你想做的事:

<DataTemplate DataType="{x:Type local:SubSectionViewModel}">
    <StackPanel>
        <Expander Header="{Binding SubSection.SubSectionName}">
            <ItemsControl ItemsSource="{Binding SubSections}"/>
        </Expander>
    </StackPanel>
</DataTemplate>

<ItemsControl Name="lstMain" ItemsSource="{Binding Sections}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <GroupBox Header="{Binding Section.SectionName}">
                <ItemsControl ItemsSource="{Binding SubSections}"/>
            </GroupBox>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
于 2013-01-03T16:49:07.280 回答
0

Section.SectionName 应为 MaterialName?

看线:

    <ItemsControl ItemsSource="{Binding SubSections}" ItemTemplate="{StaticResource BinderTemplate}" />

    <HierarchicalDataTemplate x:Key="BinderTemplate" ItemsSource="{Binding Path=SubSections}" DataType="{x:Type local:SubSectionViewModel}">

我认为,如果第一行绑定是子节,那么第二行而不是

   {Binding Path=SubSections} 

你可能会写

    {Binding}

我在您的课程中找不到 SubSectionName。

请添加更多课程

于 2013-01-03T16:23:01.827 回答