Based on the question How to associate an array of objects with elements in grid cells

Unlike the question specified in the link, I have a one-dimensional array of data that needs to be displayed in a strictly specified number of rows and columns (say 2 rows and 3 columns).

Here is an example:

There is a class that stores information about the image:

class ImageInfo { private string imgPath_; public Uri Uri { get { return new Uri(imgPath_, UriKind.Relative);} } public ImageInfo(string imgPath) { imgPath_ = imgPath; } } 

There is an array of these classes:

 ImageInfo[] imgInfo_ = new ImageInfo[] { new ImageInfo("img/0.jpg"), new ImageInfo("img/1.jpg"), new ImageInfo("img/2.jpg"), new ImageInfo("img/3.jpg"), new ImageInfo("img/4.jpg"), new ImageInfo("img/5.jpg") }; 

There is a linear array to two-dimensional converter:

 class ImgProvider : IEnumerable<IEnumerable<ImageInfo>> { readonly int ROW_COUNT = 2; readonly int COL_COUNT = 3; List<ImageInfo> _imgInfo; public ImgProvider(List<ImageInfo> imgInfo) { _imgInfo = imgInfo; } public IEnumerator<IEnumerable<ImageInfo>> GetEnumerator() { for (int i = 0; i < ROW_COUNT; i++) { yield return ColumnWraper(i); } } private IEnumerable<ImageInfo> ColumnWraper(int i) { for (int j = 0; j < COL_COUNT; j++) { int num = i == 0 ? j : j + COL_COUNT; yield return _imgInfo[num]; } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } 

Markup displaying 2 rows of images using recursive ItemsControl :

 <ItemsControl x:Name="IC" ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate> <ItemsControl ItemsSource="{Binding}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel IsItemsHost="True" Orientation="Horizontal"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Grid> <Button> <Button.Template> <ControlTemplate> <Image Source="{Binding Path=Uri}"/> </ControlTemplate> </Button.Template> </Button> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 

Installing DataContext :

 IC.DataContext = new ImgProvider(imgInfo.ToList<ImageInfo>()); 

If we set the size of Width and Height (for example 100x100) of the Grid , in which the Button with the picture is embedded, we get the following form:

enter image description here

those. all pictures fit naturally

But if you remove the size from the Grid the pictures will stretch to their true size:

enter image description here

Question : how to make so that the pictures evenly stretched in full form? Those. would all 2 rows fit and when the size of the form changes, would the size of the pictures change too?

UPD: If you use UniformGrid Columns="3" , instead of StackPanel , as recommended in the answer given, the situation becomes better, but all the same the pictures do not fit completely:

enter image description here

If you look in Live Tree View, you will see the following situation:

enter image description here

In ItemsPresenter a ItemsPresenter embedded, which apparently stretches to the content.

  • And you can put a snail in the form of pictures for experiments? - VladD
  • @VladD, no problem - here's the link to the snail - Sublihim

1 answer 1

You use the StackPanel to remove elements, it does not know how to adjust the size of the child objects to the available one. To solve this problem, it is best to replace the two-dimensional array and the nested ItemsControl (together, of course, with the data tied via the DataContext - say, replacing ImgProvider with _imgInfo ) with a regular list using a UniformGrid with Columns="3" (or Rows="2" ). Well, or if you need to leave exactly a two-dimensional array, simply replace StackPanel with ItemsControl with Rows="1" , for example.

One solution:

 <ItemsControl x:Name="IC" ItemsSource="{Binding}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid IsItemsHost="True" Columns="3" Rows="2" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Button> <Button.Template> <ControlTemplate> <Image Source="{Binding Path=Uri}"/> </ControlTemplate> </Button.Template> </Button> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 
  • My situation is this, there is one-dimensional data containing images that need to be displayed in two rows. That's why I use such a "feint with ears" - a provider who is a binj to such an ItemsControl . Could you add a xaml example to your answer to make it clearer what you mean. - Sublihim
  • one
    @Sublihim, added an example. - Surfin Bird
  • one
    @Sublihim: With the code from the answer, I get this: imgur.com/Q9fW6dH . Isn't that what you want? I just set <UniformGrid IsItemsHost="True" Rows="2" Columns="3"/> . - VladD
  • one
    @Sublihim: At the same time, DataContext is just imgInfo_ , without ImgProvider intermediate - VladD
  • one
    @Sublihim: MainWindow.xaml: pastebin.com/QXW7Q2tP MainWindow.xaml.cs: pastebin.com/zCR7gKm6 - VladD