Динамически добавленные элементы не отображаются должным образом в динамически настраиваемой сетке

У меня есть ItemsControl, который должен отображать Images в Grid.

ItemsControl выглядит следующим образом:

<ItemsControl x:Name="ICGridThumbnails">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid ShowGridLines="True" Name="GThumbnails" Loaded="GThumbnails_Loaded" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Grid.Row="{Binding GridRow}" Grid.Column="{Binding GridColumn}" Margin="{Binding Margin}" RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.EdgeMode="Aliased" Source="{Binding BitmapSource}"></Image>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Поскольку я хочу загрузить в сетку переменное количество элементов, я не могу определять строки и столбцы в разметке.

Привязки GridRow и GridColumn вычисляются в коде позади:

int countPerRow = (int)Math.Floor(Application.Current.MainWindow.ActualWidth / ThumbnailBar.ThumbnailWidthLarge);

double marginWidth = (Application.Current.MainWindow.ActualWidth - (countPerRow * ThumbnailBar.ThumbnailWidthLarge)) / (countPerRow - 1);

if (page % countPerRow == 0) {
    item.Margin = new Thickness(0, 10, 0, 0);
} else {
    item.Margin = new Thickness(marginWidth, 10, 0, 0);
}

item.GridRow = (int)Math.Floor((double)((page - 1) / countPerRow));
item.GridColumn = (page % countPerRow) - 1;

Thumbs.LargeThumbnails[page] = item;
ICGridThumbnails.ItemsSource = null;
ICGridThumbnails.ItemsSource = Thumbs.LargeThumbnails;

item - это объект со свойствами GridColumn, GridRow и BitmapSource.

После вычисления всех этих объектов и установки массива равным ItemsSource я собираюсь вычислить количество строк и столбцов:

private void GThumbnails_Loaded(Object sender, RoutedEventArgs e) {
    _GThumbnails = (Grid)sender;
    RearrangeThumbnailGrid();
}

private void RearrangeThumbnailGrid() {
    int countPerRow = (int)Math.Floor(Application.Current.MainWindow.ActualWidth / ThumbnailBar.ThumbnailWidthLarge);
    _GThumbnails.ColumnDefinitions.Clear();
    _GThumbnails.RowDefinitions.Clear();

    // Columns
    for (int i = 0; i < countPerRow; ++i) {
        ColumnDefinition cd = new ColumnDefinition();
        cd.Width = new GridLength(141);
        _GThumbnails.ColumnDefinitions.Add(cd);
    }

    // Rows
    for (int i = 0; i < (Thumbs.LargeThumbnails.Length / countPerRow) + 1; ++i) {
        RowDefinition rd = new RowDefinition();
        rd.Height = new GridLength(200);
        _GThumbnails.RowDefinitions.Add(rd);
    }
}

Как видно на моем снимке экрана, все элементы загружаются в VisualTree и имеют правильные значения Column и Row. Также сетка будет отображаться правильно. Кажется, что свойство BitmapSource работает правильно, потому что на моем снимке экрана можно увидеть Image (35 на белом фоне).

Проблема только в том, что все элементы как бы отображаются в «первой» ячейке в левом верхнем углу. Также возможно, что значения для Row и Column игнорируются. введите описание изображения здесь

Я пытался использовать предложения из здесь, но это не сработало.


person tg24    schedule 04.06.2018    source источник
comment
Фактическая проблема заключается в том, что Image в DataTemplate не является прямым потомком Grid. Вот почему свойства должны быть установлены в ItemContainer.   -  person Clemens    schedule 04.06.2018
comment
Да я так понимаю из ответа mm8s, спасибо тоже!   -  person tg24    schedule 04.06.2018
comment
Вы также можете привязать количество строк и столбцов, как показано в этот ответ.   -  person Clemens    schedule 04.06.2018


Ответы (1)


Задайте присоединенные свойства Grid.Row и Grid.Column для ItemContainer:

<ItemsControl x:Name="ICGridThumbnails">
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Grid.Row" Value="{Binding GridRow}" />
            <Setter Property="Grid.Column" Value="{Binding GridColumn}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid ShowGridLines="True" Name="GThumbnails" Loaded="GThumbnails_Loaded" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Image Margin="{Binding Margin}" RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.EdgeMode="Aliased" Source="{Binding BitmapSource}"></Image>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
person mm8    schedule 04.06.2018
comment
Отлично работает, спасибо! - person tg24; 04.06.2018