C# WPF 使用 ItemsControl 管理嵌套结构

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17493201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:09:45  来源:igfitidea点击:

C# WPF managing nested structures using ItemsControl

c#wpfxamlgriditemscontrol

提问by Kamil Solecki

So, I have already posted a question about the nested controls structure in WPF, it is here: Nested controls structure - in XAML or C#?And I have received a solution as follows:

所以,我已经发布了一个关于 WPF 中嵌套控件结构的问题,它在这里: 嵌套控件结构 - 在 XAML 或 C# 中?我收到了如下解决方案:

<ItemsControl ItemsSource="{Binding SomeCollectionOfViewModel}">
   <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <UniformGrid/>
      </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
   <ItemsControl.ItemTemplate>
       <DataTemplate>
          <ItemsControl ItemsSource="{Binding SomeCollection}">   <!-- Nested Content -->
              ...
       </DataTemplate>
   <ItemsControl.ItemTemplate>
</ItemsControl>

I have used that solution, comming up with this:

我已经使用了那个解决方案,提出了这个:

<!-- The UniformGrids - boxes -->
<ItemsControl ItemsSource="{Binding UniformGridCollection}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>

                <!-- The TextBoxes - Cells -->
                <ItemsControl ItemsSource="{Binding TextBoxCollection}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>

            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Here is the C# side:

这是 C# 方面:

public partial class MainWindow : Window
    {
        private readonly ObservableCollection<UniformGrid> uniformGridCollection = new ObservableCollection<UniformGrid>();
        public ObservableCollection<UniformGrid> UniformGridCollection { get { return uniformGridCollection; } }
        private readonly ObservableCollection<UniformGrid> textBoxCollection = new ObservableCollection<UniformGrid>();
        public ObservableCollection<UniformGrid> TextBoxCollection { get { return textBoxCollection; } }
        public MainWindow()
        {
            InitializeComponent();
            for (int i = 1; i <= 9; i++)
            {
                UniformGrid box = new UniformGrid();
                UniformGridCollection.Add(box);
                UniformGrid cell = new UniformGrid();
                TextBoxCollection.Add(cell);
            }
            DataContext = this;
        }
    }

But somehow the "Cells" - textboxes, that are inside the uniformgrids, do not create. Instead, I get only 9 uniform grids contain in one big uniform Grid (specified in Paneltemplate). I have checked the prgram with Snoop v 2.8.0: http://i40.tinypic.com/htzo5l.jpg

但不知何故,“单元格” - 位于uniformgrids 内的文本框不会创建。相反,我在一个大的统一网格(在面板模板中指定)中只得到 9 个统一网格。我已经用 Snoop v 2.8.0 检查了程序:http: //i40.tinypic.com/htzo5l.jpg

The question is:Could somebody tell me, why the inside structure(textboxes) arent created?

问题是:有人可以告诉我,为什么没有创建内部结构(文本框)?

回答by Federico Berasategui

You're not defining any TextBoxes anywhere, That's why you're not getting any TextBoxes in the Visual Tree:

你没有在任何TextBox地方定义任何es,这就是为什么你没有TextBox在 Visual Tree 中得到任何es:

<Window x:Class="MiscSamples.NestedItemsControls"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="NestedItemsControls" Height="300" Width="300">
    <ItemsControl ItemsSource="{Binding Level1}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ItemsControl ItemsSource="{Binding Level2}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding Value}"/> <!-- You Are missing this! -->
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

Also, as mentioned in the comment, your Collections should be of ViewModel or Model types, not UI types:

此外,如评论中所述,您的集合应该是 ViewModel 或 Model 类型,而不是 UI 类型:

ViewModels:

视图模型:

public class NestedItemsViewModel
{
    public List<Level1Item> Level1 { get; set; }
}

public class Level1Item
{
    public List<Level2Item> Level2 { get; set; }
}

public class Level2Item
{
    public string Value { get; set; }
}

Code Behind:

背后的代码:

public partial class NestedItemsControls : Window
{
    public NestedItemsControls()
    {
        InitializeComponent();

        DataContext = new NestedItemsViewModel()
                          {
                              Level1 = Enumerable.Range(0, 10)
                                                 .Select(l1 => new Level1Item()
                                                    {
                                                        Level2 = Enumerable.Range(0, 10)
                                                                           .Select(l2 => new Level2Item { Value = l1.ToString() + "-" + l2.ToString() })
                                                                           .ToList()
                                                    })
                                                  .ToList()
                          };
    }
}

Notice that you will have to change the Lists to ObservableCollections if you expect these collections to change dynamically during runtime.

请注意,如果您希望这些集合在运行时动态更改,则必须将Lists更改为s ObservableCollection

Also notice you have to implement INotifyPropertyChangedproperly.

另请注意,您必须INotifyPropertyChanged正确实施。