This is my XAML right now:
<Window x:Class="GridDemo.SubWindow"
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:GridDemo"
d:DataContext="{d:DesignInstance local:ViewModel, IsDesignTimeCreatable=True}"
mc:Ignorable="d"
Title="Window" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView
ItemsSource="{Binding Animals}"
SelectedItem="{Binding SelectedAnimal}"
Grid.Row="0"/>
<Button
Command="{Binding AddAnimalCommand}"
Content="Add Animal"
HorizontalAlignment="Right"
Grid.Row="1"/>
<ListView
ItemsSource="{Binding Vegetables}"
SelectedItem="{Binding SelectedVegetable}"
Grid.Row="2"/>
<Button
Command="{Binding AddVegetableCommand}"
Content="Add Vegetable"
HorizontalAlignment="Right"
Grid.Row="3"/>
</Grid>
When I run, it shows this:
Problem right away, it's using too much vertical space.
A thing I like and want to keep is that if I shrink it so that it's too small to show both listviews in their entirety, the listboxes shrink and automatically get scroll bars added, but the buttons stay visible no matter what.
But the main problem happens when the listviews are different sizes. They will always use half of the available space to them. Suppose I have ten animals and five vegetables, and my window is tall enough to hold 15 items. I would want the vegetable listview to ask for only as much space as it needs, letting the animal listview ask for all of the remaining space. Instead, both listviews ask for 50% of the remaining space, causing the animal listview to be too small and the vegetable listview to be too big.
I think that what I want is for the listview rows to behave like Height="Auto" when there's enough room for them, and to behave like Height="*" when there isn't.
To get the effect you're looking for, I'd do something like this:
I've used an implementation of
IMultiValueConverter
to generate the row height proportions. It's in a resource dictionary with a key of "gpc" and is implemented as follows:I have used
ICollection
assuming you have some kind ofObservableCollection<T>
for your collections.I find this works quite well, but obviously one thing it depends on is each
ListViewItem
being roughly the same height in eachListView
, otherwise you may need to cater for the height difference.I've also put a bit of a fail-safe in, where if the window's height goes below a certain value, the proportion becomes 1:1.
If the proportions are ever out of control, e.g., 300:1, you could always pass in both collections and calculate more appropriate proportions based on that, e.g., you might decide that 4:1 is the biggest difference you'd tolerate and you'd default to that if it ever got bigger.