好吧,很抱歉我以前搞砸了。
情况如下:我有两个自定义对象定义如下: MainObject:
public class MainObject
{
private string mainObjectName;
public string MainObjectName { get { return mainObjectName; } }
private List<SubObject> subObjectData;
public List<SubObject> SubObjectData { get { return subObjectData; } }
public MainObject(string name, List<SubObject> objectData)
{
mainObjectName = name;
subObjectData = objectData;
}
}SubObject:
public class SubObject
{
private string subObjectName;
public string SubObjectName { get { return subObjectName; } }
private List<int> integerData;
public List<int> IntegerData { get { return integerData; } }
public SubObject(string name, List<int> data)
{
subObjectName = name;
integerData = data;
}
}为了简单起见,我还有一个视图模型,它使用这两个对象定义了一些数据,如下所示:
public List<Model.MainObject> VMList = new List<Model.MainObject>()
{
new Model.MainObject("MainItem1", new List<Model.SubObject>()
{
new Model.SubObject("SubItem1", new List<int>() { 1,6,3}),
new Model.SubObject("SubItem2", new List<int>() { 5,2,9})
}),
new Model.MainObject("MainItem2", new List<Model.SubObject>()
{
new Model.SubObject("SubItem1", new List<int>() { 0,3,1}),
new Model.SubObject("SubItem2", new List<int>() { 7,5,2})
})
};现在我有了下面的UI
<Grid>
<ItemsControl Name="MainObjectIC">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding MainObjectName}"/>
<ItemsControl Name="SubObjectIC">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding SubObjectName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>我在后面的代码中分配ItemsSource的MainObjectIC,如下所示:
ViewModel.VM dc = new ViewModel.VM();
public MainWindow()
{
InitializeComponent();
DataContext = dc;
MainObjectIC.ItemsSource = dc.VMList;
}我还想将ItemsSource分配给SubObjectIC,但要做到这一点,我必须得到那个ItemsControl对象。这就是我想要达到的目标。
据我所知,从后面的代码中分配ItemsSource属性可能是非常糟糕和无用的。
发布于 2017-03-21 19:21:42
感谢您对代码示例的改进。它仍然不完全,但它足够接近,能够提供一个答案。
在您的示例中,主要缺少的是简单地添加必要的{Binding}表达式。特别是:
<ItemsControl Name="SubObjectIC" Grid.Column="1"
ItemsSource="{Binding SubObjectData}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding SubObjectName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>项的上下文已经是MainObject类型的对象(这就是TextBlock绑定工作的原因)。因此,剩下的工作就是将ItemsSource属性绑定到MainObject.SubObjectData属性。
(我必须添加Grid.Column赋值,这在上面的示例中似乎是缺失的。)
以上的改变完全足以让你的榜样如你所愿发挥作用。但是,您也可以通过对顶层控件使用相同的基本方法来改进代码。为此,需要将VM.VMList字段更改为属性(WPF只绑定到属性,而不是字段):
class VM
{
public List<MainObject> VMList { get { return _vmList; } }
private readonly List<MainObject> _vmList = new List<MainObject>()
{
new MainObject("MainItem1", new List<SubObject>()
{
new SubObject("SubItem1", new List<int>() { 1,6,3}),
new SubObject("SubItem2", new List<int>() { 5,2,9})
}),
new MainObject("MainItem2", new List<SubObject>()
{
new SubObject("SubItem1", new List<int>() { 0,3,1}),
new SubObject("SubItem2", new List<int>() { 7,5,2})
})
};
}然后,只需删除构造函数中的显式赋值:
public MainWindow()
{
InitializeComponent();
DataContext = dc;
}通过这些更改,您的XAML不再需要提供任何控件名称,您可以直接绑定到相关属性:
<Window x:Class="TestSO42929995WpfNestedData.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestSO42929995WpfNestedData"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ItemsControl ItemsSource="{Binding VMList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding MainObjectName}"/>
<ItemsControl Grid.Column="1"
ItemsSource="{Binding SubObjectData}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding SubObjectName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>在上面可能并不明显的一个关键点是,每个控件都有一个DataContext。使用{Binding}语法时,默认情况下属性路径相对于该上下文。在顶层控件中,上下文是将其设置为构造函数的内容。但是在单个列表项模板中,上下文是该列表项的单个数据对象,在您的示例中,该对象是MainObject对象。因此,在这种情况下,您只需绑定到SubObjectData属性,就像绑定到MainObjectName一样。它的工作原理是完全一样的,也是出于同样的原因。
https://stackoverflow.com/questions/42929995
复制相似问题