动态添加的元素无法在动态调整的网格中正确显示[重复]

Posted

技术标签:

【中文标题】动态添加的元素无法在动态调整的网格中正确显示[重复]【英文标题】:Dynamically added elements are not displayed properly in a dynamically adjusted grid [duplicate] 【发布时间】:2018-11-13 21:30:27 【问题描述】:

我有一个ItemsControl,它应该在Grid 中显示Images

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>

由于我想将可变数量的元素加载到网格中,我无法在标记中定义行和列。

绑定GridRowGridColumn 在后面的代码中计算:

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 是一个具有GridColumnGridRowBitmapSource 属性的对象。

计算完所有这些对象并将数组设置为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 中,并且它们具有正确的 ColumnRow 值。网格也将正确显示。 BitmapSource 属性似乎工作正常,因为可以在我的屏幕截图上看到 Image(白色背景上的 35)。

唯一的问题是所有项目似乎都显示在左上角的“第一个”单元格中。 RowColumn 的值也可能被忽略。

我尝试使用来自here 的建议,但这不起作用。

【问题讨论】:

实际问题是DataTemplate中的Image不是Grid的直接子级。这就是为什么必须在 ItemContainer 上设置属性的原因。 是的,我从mm8s的回答中了解到,也谢谢! 还可以绑定行数和列数,如this answer所示。 【参考方案1】:

设置ItemContainer的Grid.RowGrid.Column附加属性:

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

【讨论】:

完美运行,谢谢!

以上是关于动态添加的元素无法在动态调整的网格中正确显示[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用 Javascript 动态添加时,SVG 元素无法正确缩放

是否可以让 NCurses CDK 矩阵动态调整到终端窗口的大小?

Kivy中的动态网格,每个网格元素包含多个小部件

无法在动态添加的元素上显示 mCustomScrollBar

重复网格中的用户输入以填充动态下拉列表

选择下拉菜单后,动态输入字段无法正确显示