0

I've got a ItemsControl which should display Images in a Grid.

The ItemsControl looks like the following:

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

Since I want to load a variable amount of elements into the grid, I'm not able to define the rows and columns in the markup.

The Bindings GridRow and GridColumn are calculated in the code behind:

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 is a object with the properties GridColumn, GridRow and BitmapSource.

After calculating all of these objects and set the array to the ItemsSource I'm going to calculate the number of rows and columns:

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

As can be seen on my screenshot, all Items are loaded into the VisualTree and they have the correct Column and Row values. Also the grid will be displayed correctly. The BitmapSource property seems to work properly because one can see a Image (the 35 on white background) on my screenshot.

The only problem is that all items seem to be displayed in the "first" cell in the left upper corner. It also may be possible that the values for Row and Column are ignored. enter image description here

I tried to use suggestions from here, but that doesn't work.

tg24
  • 161
  • 3
  • 22
  • The actual problem is that the Image in the DataTemplate is not a direct child of the Grid. That's why the properties have to be set on the ItemContainer. – Clemens Jun 04 '18 at 14:10
  • Yes, I understand that from mm8s answer, thank you too! – tg24 Jun 04 '18 at 14:13
  • You may also bind the row and column count, as shown in [this answer](https://stackoverflow.com/questions/9000549/how-can-i-dynamically-add-a-rowdefinition-to-a-grid-in-an-itemspaneltemplate/9007442#9007442). – Clemens Jun 04 '18 at 14:18

1 Answers1

1

Set the Grid.Row and Grid.Column attached properties of the 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>
mm8
  • 163,881
  • 10
  • 57
  • 88