HierarchicalDataTemplate不起作用

时间:2013-01-03 16:01:24

标签: c# wpf xaml hierarchicaldatatemplate

我正在尝试使用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>

到目前为止我所拥有的。

的Xaml:

<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;
        }
    }
}

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:1)

HierarchicalDataTemplate的替代方法是向数据模板中的ItemsControl添加Expander,然后将ItemsSource绑定在那里。

此外,由于您在数据模板定义中指定了DataType,因此您不必为您的顶级ItemTemplate按键名称直接设置ItemsControl。< / p>

如果你像这样修改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>

答案 2 :(得分:0)

Section.SectionName应为MaterialName?

Look Lines:

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

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

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

   {Binding Path=SubSections} 
你可能会写

    {Binding}

我在你的班级找不到SubSectionName。

请添加更多课程