С# WPF управляет вложенными структурами с помощью ItemsControl

Вопрос:

Итак, я уже разместил вопрос о структуре вложенных элементов управления в WPF, это здесь: Структура вложенных элементов управления — в XAML или С#? И я получил решение следующим образом:

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

Я использовал это решение, воспользовавшись этим:

<!-- 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>

Вот сторона С#:

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;
}
}

Но так или иначе «Ячейки» — текстовые поля, которые находятся внутри единых градиентов, не создаются. Вместо этого я получаю только 9 равномерных сеток в одной большой однородной сетке (заданной в Paneltemplate). Я проверил программу с помощью Snoop v 2.8.0: http://i40.tinypic.com/htzo5l.jpg

Возникает вопрос: может ли кто-нибудь сказать мне, почему создана внутренняя структура (текстовые поля) arent?

Лучший ответ:

Вы не определяете какие-либо TextBox любом месте, поэтому вы не получаете никаких TextBox полей в Visual Tree:

<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>

Кроме того, как упоминалось в комментарии, ваши коллекции должны быть типов ViewModel или Model, а не типов пользовательского интерфейса:

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; }
}

Код:

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()
                          };
    }
}

Обратите внимание, что вам придется изменить List на ObservableCollection если вы ожидаете, что эти коллекции будут динамически изменяться во время выполнения.

Также обратите внимание, что вы должны правильно реализовать INotifyPropertyChanged.

Оцените статью
TechArks.Ru
Добавить комментарий