簡體   English   中英

如何分配ItemsSource屬性

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM