将分层对象数据绑定到ListBox

时间:2011-05-14 16:04:03

标签: wpf data-binding listbox hierarchicaldatatemplate

我正在尝试使用WPF中的数据绑定来填充包含来自对象源的数据的ListBox。

源是一个ObjectDataProvider,其数据是从xml文件加载的。我读入XML文件,填写适当的数据结构,然后将ObjectDataProvider的ObjectInstance设置为数据结构。

这是数据结构:

public class Element
{
       public decimal myValue;

       public decimal df_myValue { get { return myValue; } set { this.myValue = value; } }
}

public class BasicSet
{
       public Element[] elementSet;

       public Element[] df_elementSet { get { return elementSet; } set { this.elementSet = value; } }
}

public class DataSet
{
        public BasicSet[] basicSet;

    public BasicSet[] df_basicSet { get { return basicSet; } set { this.basicSet = value; } }
}

这是XAML:

<UserControl.Resources>
    <ResourceDictionary>
        <ObjectDataProvider x:Key="TheData" />

        <DataTemplate x:Key="ElementTemplate">
            <StackPanel>
                <TextBox Text="{Binding, Path=df_myValue}" />
            </StackPanel>
        </DataTemplate>

        <HierarchicalDataTemplate x:Key="ElementSetTemplate" ItemsSource="{Binding Path=df_elementSet}" ItemTemplate="{StaticResource ElementTemplate}">
        </HierarchicalDataTemplate>

    </ResourceDictionary>
</UserControl.Resources>

<Grid>
    <ListBox ItemsSource="{StaticResource TheData}" ItemTemplate="{StaticResource ElementSetTemplate}">
    </ListBox>
</Grid>

以下是加载xml数据的代码隐藏:

    private DataSet m_dataSet;
    private ObjectDataProvider mODP;

    public void LoadXml(EditorContext context, XmlValidator.Context validator, XmlDocument doc)
    {
        mODP = FindResource("TheData") as ObjectDataProvider;

        XmlSerializer xs = new XmlSerializer(typeof(DataSet));
        XmlReader r = new XmlNodeReader(doc.DocumentElement);
        m_dataSet = (DataSet)xs.Deserialize(r);

        mODP.ObjectInstance = m_dataSet;
    }

期望的结果是ListBox将为数据结构中的每个元素提供TextBox。请注意,由于某种原因,数据结构是分层的。我不能扁平化数据结构来简化问题。

我确信xml数据正确地加载到数据结构中,因为我可以放置一个断点并检查它,所有数据看起来都很好。但是当我运行程序时,ListBox中没有任何内容。

感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

我弄清楚我做错了什么。有几件事是错的。以下是要点:

1)我应该使用itemsControl

2)我不需要使用HierarchicalDataTemplate

3)我需要三个级别的控件:itemsControl中的itemsControl内的TextBox ......这可以使用两个DataTemplates来完成。顶级itemsControl引用一个包含内部itemsControl的DataTemplate。然后itemsControl引用一个包含内部TextBox的DataTemplate。

这是正确的xaml:

<UserControl.Resources>
    <ResourceDictionary>
        <ObjectDataProvider x:Key="TheData" />

        <DataTemplate x:Key="ElementTemplate">
            <TextBox Text="{Binding Path=df_myValue}"/>
        </DataTemplate>

        <DataTemplate x:Key="ElementSetTemplate">
            <GroupBox Header="I am a GroupBox">
                <ItemsControl ItemsSource="{Binding Path=df_elementSet}" ItemTemplate="{StaticResource ElementTemplate}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </GroupBox>
        </DataTemplate>

    </ResourceDictionary>
</UserControl.Resources>

<Grid>
    <ItemsControl ItemsSource="{Binding Source={StaticResource TheData}, Path=df_basicSet}" ItemTemplate="{StaticResource ElementSetTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>

希望这有助于其他人...