使用ControlTemplate的HierarchicalDataTemplate和HeaderedItemsControl无法显示嵌套数据

时间:2009-11-22 05:05:06

标签: wpf xaml hierarchicaldatatemplate xmldataprovider

我可以使用此模式与MenuTreeView一起使用但是当我尝试使用HeaderedItemsControl时,我一定会遗漏一些内容:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Page.Resources>

    <HierarchicalDataTemplate x:Key="MenuItemTemplate" ItemsSource="{Binding XPath=foo}">
        <AccessText Text="{Binding XPath=@a}" />
    </HierarchicalDataTemplate>

    <Style TargetType="HeaderedItemsControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type HeaderedItemsControl}">
                    <StackPanel>
                        <ContentPresenter ContentSource="Header"/>
                        <ItemsPresenter Margin="10,0,0,0" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <XmlDataProvider x:Key="RootXml" XPath="/root/foo">
        <x:XData>
            <root xmlns="">
                <foo a="one">
                    <foo a="two" b="wow, two" />
                    <foo a="three" b="wow, three" />
                    <foo a="four" b="wow, four" />
                </foo>
                <foo a="one again">
                    <foo a="two others" b="wow, two others" />
                    <foo a="three the hard way" b="wow, three again" />
                </foo>
            </root>
        </x:XData>
    </XmlDataProvider>

</Page.Resources>

<StackPanel>
    <HeaderedItemsControl
        Header="My Foo List"
        ItemTemplate="{Binding Source={StaticResource MenuItemTemplate}}"
        ItemsSource="{Binding Source={StaticResource RootXml}}">
    </HeaderedItemsControl>
</StackPanel>
</Page>

在XamlPadX中,显示:

My foo list
    one
    one again

我是否需要对ControlTemplate执行某些操作才能正确显示数据?或者我需要更精细(或额外)HierarchicalDataTemplate?另外:我们如何显示foo/@b数据?

3 个答案:

答案 0 :(得分:3)

这是一个迟到的答案。一直试图解决这个问题,但对上述答案和/或链接答案中的推理不满意,因为XAML模式应该在所有控件之间相同。

使用jetbrains dotPeek一段时间之后,梳理思想TreeView Control的答案终于非常简单了。 TreeView和TreeViewItem将 IsItemItsOwnContainerOverride GetContainerForItemOverride 覆盖到将保存子项的控件(TreeView案例中的TreeViewItem)。您可以创建两个简单的自定义控件来处理此问题。

您的 HeaderedItemControl 类将是这样的:

public class MyHierarchicalViewItem : HeaderedItemsControl
{
    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is MyHierarchicalViewItem;
    }

    protected override DependencyObject GetContainerForItemOverride()
    {
        return (DependencyObject)new MyHierarchicalViewItem();
    }
}

您的ItemControl(相当于TreeView或Menu)将是:

public class MyHierarchicalView:ItemsControl 
{
    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is MyHierarchicalViewItem;
    }

    protected override DependencyObject GetContainerForItemOverride()
    {

        return (DependencyObject) new MyHierarchicalViewItem();
    }
}

你的XAML基本上是相同的,只需引用正确的控件并添加适当的命名空间(我的情况xmlns:myControls =“clr-namespace:”)。

<UserControl.Resources>

        <HierarchicalDataTemplate x:Key="MenuItemTemplate" ItemsSource="{Binding XPath=foo}">
            <AccessText Text="{Binding XPath=@a}" />
        </HierarchicalDataTemplate>

        <Style TargetType="{x:Type myControls:MyHierarchicalViewItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type myControls:MyHierarchicalViewItem}">
                        <StackPanel>
                            <ContentPresenter ContentSource="Header"/>
                            <ItemsPresenter Margin="10,0,0,0" />
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <XmlDataProvider x:Key="RootXml" XPath="/root/foo">
            <x:XData>
                <root xmlns="">
                    <foo a="one">
                        <foo a="two" b="wow, two" />
                        <foo a="three" b="wow, three" />
                        <foo a="four" b="wow, four" />
                    </foo>
                    <foo a="one again">
                        <foo a="two others" b="wow, two others" />
                        <foo a="three the hard way" b="wow, three again" />
                    </foo>
                </root>
            </x:XData>
        </XmlDataProvider>

        </UserControl.Resources>

    <StackPanel>
        <myControls:MyHierarchicalViewItem
        Header="My Foo List"
        ItemTemplate="{Binding Source={StaticResource MenuItemTemplate}}"
        ItemsSource="{Binding Source={StaticResource RootXml}}">
        </myControls:MyHierarchicalViewItem>
    </StackPanel>

</UserControl>

答案 1 :(得分:0)

这似乎就是这笔交易:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Page.Resources>

    <XmlDataProvider x:Key="RootXml" XPath="/root/foo">
        <x:XData>
            <root xmlns="">
                <foo a="one" b="test1">
                    <foo a="two" b="wow, two" />
                    <foo a="three" b="wow, three" />
                    <foo a="four" b="wow, four" />
                </foo>
                <foo a="one again" b="test2">
                    <foo a="two others" b="wow, two others" />
                    <foo a="three the hard way" b="wow, three again" />
                </foo>
            </root>
        </x:XData>
    </XmlDataProvider>

    <Style TargetType="HeaderedItemsControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type HeaderedItemsControl}">
                    <StackPanel>
                        <ContentPresenter ContentSource="Header"/>
                        <ItemsPresenter Margin="10,0,0,0" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <HierarchicalDataTemplate x:Key="NestedFooItemTemplate">
        <AccessText Text="{Binding XPath=@b}" />
    </HierarchicalDataTemplate>

    <HierarchicalDataTemplate x:Key="FooItemTemplate">
        <StackPanel>
            <AccessText Text="{Binding XPath=@a}" />
            <HeaderedItemsControl
                Header="My Nest"
                ItemTemplate="{Binding Source={StaticResource NestedFooItemTemplate}}"
                ItemsSource="{Binding XPath=./foo}"
                Margin="10,0,0,0" />
        </StackPanel>
    </HierarchicalDataTemplate>

</Page.Resources>

<StackPanel>
    <HeaderedItemsControl
        Header="My Foo List"
        ItemTemplate="{Binding Source={StaticResource FooItemTemplate}}"
        ItemsSource="{Binding Source={StaticResource RootXml}}">
    </HeaderedItemsControl>
</StackPanel>
</Page>

答案 2 :(得分:0)

HierarchicalDataTemplate用于具有自动子元素扩展的树视图。在您的情况下,您只需使用普通DataTemplate