我正在尝试使用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中没有任何内容。
感谢任何帮助。
答案 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>
希望这有助于其他人...