2017-03-21 69 views
3

好吧,對不起我以前的混亂。如何分配ItemsSource屬性

的情況是這樣的: 我有兩個自定義對象定義如下: 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; 
    } 
} 

我也有一個視圖模型爲簡單起見使用定義了一些數據這兩個對象如下: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屬性。

+0

我認爲綁定「孩子」集合的相對來源應該有效。我只是爲了找到祖先類型的窗口,但我認爲它會允許更多的類型。 –

+0

有'{綁定...}'綁定所有標記。爲什麼用於'RelicItemsSource'的ItemsSource不能被xaml綁定? – ASh

+0

是的,但我不知道如何去做,因爲RelicItemsSource應該依賴綁定到ComponentsItemsSource的Object。另外我想我需要將DataContext綁定到'this'而不是我自己的客體對象。 –

回答

2

感謝您改進您的代碼示例。它還不完整,但它足夠接近,能夠提供答案。

在你的例子中,缺少的主要是簡單地添加必要的{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> 

關鍵POI在上面可能不明顯的nt是每個控件都有DataContext。當您使用{Binding}語法時,默認情況下,屬性路徑與該上下文相關。在頂層控件中,上下文就是您將其設置爲構造函數中的內容。但是在單個列表項模板中,上下文是該列表項的單個數據對象,在您的情況下,該對象是MainObject對象。所以在這種情況下,您只需綁定到SubObjectData屬性,就像綁定到MainObjectName一樣。它的工作原理完全相同,原因相同。

+0

哦,上帝請殺了我,我真是個白癡。非常感謝浪費時間 –

+0

@George:無需對自己如此刻苦。如果你真的是一個白癡,你就不會接受關於你的原始帖子的反饋以及如何改進它(相信我,Stack Overflow上有很多這樣的人)。雖然我懷疑Stack Overflow存在類似的問題,但我沒有找到與您的完全相同的內容。即使有,現在也有一個很好的,簡單的代碼示例來說明問題和答案,這幾乎不會浪費時間。 :) –

+0

感謝您的支持和偉大的態度:) –