0

I'm having trouble with a Grid when the parent is a Viewbox.

I have an image selector in WPF consisting of a two column Grid.

  1. The right column is a ListBox of thumbnails taking 25% of the entire width of the grid.
  2. When a thumbnail is selected, it is presented in the left column taking up the remaining space.

The mail image should stretch keeping its aspect ratio until one of the dimensions reaches the either the column width or the grid's height.

I'd like to be able to scale the entire image selector uniformly so I surrounded it in a Viewbox. However, after adding the ViewBox it seems to have broken Grid and ListBox behaviours:

  1. Clicking on the second image selects the wrong image
  2. The grid column ratios aren't respected when images of different aspect ratios are selected. Eg if I choose a thin image like the first, then the columns are more like 50/50 ratio.

I'm not tied to having Viewbox or Grid controls, I just would like the functionality I get from the grid and ListBox when the Viewbox isn't there and add uniform scaling of the grid and its children.

I've extracted the relevant code below:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace WpfViewBox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Images = new List<ImageSource>()
            {
                new BitmapImage(new Uri("https://images.unsplash.com/photo-1648720666508-102320ea1c11?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxMHx8fGVufDB8fHx8")),
                new BitmapImage(new Uri("https://images.unsplash.com/photo-1648672231811-4b3b3642f2e0?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwzOXx8fGVufDB8fHx8")),
                new BitmapImage(new Uri( "https://images.unsplash.com/photo-1648687735004-acb0bb16c8d9?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxNTB8fHxlbnwwfHx8fA%3D%3")),
            };

            ImageListBox.SelectedIndex = 0;
        }

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            MainImage.Source = (ImageSource)ImageListBox.SelectedItem;
        }

        public IEnumerable Images { get; set; }
    }
}
<Window x:Class="WpfViewBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfViewBox"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Viewbox>
        <Grid Margin="8" MaxHeight="240" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width=".25*" />
            </Grid.ColumnDefinitions>

            <Image Grid.Column="0"
                   x:Name="MainImage"
                   Height="240"
                   Stretch="Uniform"
                   StretchDirection="Both"/>

            <ListBox x:Name="ImageListBox" 
                     Grid.Column="1" 
                     SelectionChanged="ListBox_SelectionChanged" 
                     ItemsSource="{Binding Images, RelativeSource={RelativeSource AncestorType=Window}}"
                     ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
                     ScrollViewer.VerticalScrollBarVisibility="Hidden"
                     HorizontalContentAlignment="Stretch">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Image Source="{Binding}"
                               HorizontalAlignment="Center"
                               Height="120"
                               Stretch="Uniform"
                               StretchDirection="Both"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Viewbox>
</Window>

Note: the vertical scrollbar is hidden, but you can either use the arrow keys to move one at a time or the mouse wheel to scroll multiple (depending on your system settings).

camios
  • 182
  • 13

1 Answers1

0

As the first comment from @Alex.Wei under this question Using Viewbox to scale Grid containing Labels and Textboxes states, adding fixed height and width to the grid addresses the problems.

Also mentioned as answer to ColumnDefinition.Width of Grid in Viewbox being set to Auto?

Usually setting a fixed height/width prevents the grid from growing, so its counterintuitive to specify them, but having a Viewbox as a parent changes this behaviour

camios
  • 182
  • 13