Как сделать генерацию сетки в WPF?

У меня есть вот такая сетка

        <ScrollViewer Margin="126,0,0,2" Grid.ColumnSpan="2" Grid.Row="1">
            <Grid Height="1182">
                <Grid Margin="0,0,-16,0">

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="130*"/>
                        <ColumnDefinition Width="130*"/>
                        <ColumnDefinition Width="130*"/>
                        <ColumnDefinition Width="62*"/>
                        <ColumnDefinition Width="21*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="21"/>
                        <RowDefinition Height="107"/>
                        <RowDefinition Height="107"/>
                        <RowDefinition Height="107"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid Grid.ColumnSpan="5" Grid.RowSpan="5">
                        <Grid/>
                    </Grid>

                    <Grid Grid.Row="2"/>
                    <Grid Grid.Row="3" HorizontalAlignment="Right" Width="130"/>
                    <Grid Grid.Row="1" Grid.Column="1"/>
                    <Grid Grid.Row="2" Grid.Column="1"/>
                    <Grid Grid.Row="3" Grid.Column="1"/>
                    <Grid Grid.Row="1" Grid.Column="2"/>
                    <Grid Grid.Row="2" Grid.Column="2"/>
                    <Grid Grid.Row="3" Grid.Column="2"/>
                </Grid>
            </Grid>
        </ScrollViewer>

введите сюда описание изображения

И на этом гриде есть скролвювер, как сделать чтобы такая же сетка генерировалась внизу


Ответы (1 шт):

Автор решения: aepot

Для презентации коллекций в интерфейсе есть контролы для коллекций - ListView, ListBox, и другие. И самый простой и базовый из них - ItemsControl.

Не используйте отступы для позиционирования, используйте их только для отступов.

Проще всего сделать этот фокус с помощью привязки данных и ItemsControl.

Пусть класс данных будет такой.

public class DataItem
{
    public string Name { get; set; }
}

Чтобы незаморачивать вас реализацией интерфейса INotifyPropertyChanged, я создам свойство только для чтения, в нем будет жить коллекция данных. ObservableCollection - то же самое что и List, только интерфейс умеет ослеживать в ней изменения.

public class MainWindow : Window
{
    public ObservableCollection<DataItem> Items { get; } = new ObservableCollection<DataItem>();

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    public void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Items.Add(new DataItem { Name = "Hello" });
    }
}
<Grid>
   <Grid.ColumnDefinitions>
       <ColumnDefinition Width="Auto" MinWidth="130"/>
       <ColumnDefinition/>
   </Grid.ColumnDefinitions>
   <ScrollViewer Grid.Column="1">
       <ItemsControl ItemsSource="{Binding Items}" Margin="20,0">
           <ItemsControl.ItemTemplate>
               <DataTemplate>
                   <Grid Width="130" Height="107">
                       <TextBlock Text="{Binding Name}"/>
                       <!-- здесь сделайте разметку ячейки -->
                   </Grid>
               <DataTemplate>
           </ItemsControl.ItemTemplate>
           <ItemsControl.ItemsPanel>
               <ItemsPanelTemplate>
                   <WrapPanel/>
                   <!-- та самая панель, которая автоматом переносит лишние элементы на новую строчку -->
               </ItemsPanelTemplate>
           </ItemsControl.ItemsPanel>
       </ItemsControl>
   </ScrollViewer>
</Grid>

При добавлении и удалении элементов в коллекции Items они автоматически будут появляться и удаляться из интерфейса в режиме реального времени.

Свойство Items нельзя переприсвоить, если это мешает, реализуйте INotifyPropertyChanged, это я показывал много раз ранее, например здесь.

Помимо WrapPanel есть еще StackPanel, UniformGrid, DockPanel и другие менее популярные панели, познакомьтесь с ними.

→ Ссылка