[英]How to assign ItemsSource property
好的,抱歉我以前的爛攤子。
情況是這樣的:我有兩個自定義對象定義如下: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;
}
}
子對象:
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;
}
}
我還有一個viewmodel,為了簡單起見,使用這兩個對象定義了一些數據,如下所示:VM
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>
我在后面的代碼中分配MainObjectIC的ItemsSource,如下所示:
ViewModel.VM dc = new ViewModel.VM();
public MainWindow()
{
InitializeComponent();
DataContext = dc;
MainObjectIC.ItemsSource = dc.VMList;
}
我還想將ItemsSource分配給SubObjectIC,但為了做到這一點,我必須得到ItemsControl對象。 這就是我想要實現的目標。
根據我的理解,從后面的代碼中分配ItemsSource屬性可能是非常非常糟糕和無用的。
感謝您改進代碼示例。 它仍然不完整,但足夠接近能夠提供答案。
在您的示例中,缺少的主要是簡單地添加必要的{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
。 它的工作方式完全相同,原因相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.