1

这是我现在的 XAML:

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

当我运行时,它显示:

在此处输入图像描述

问题马上出现,它使用了太多的垂直空间。

我喜欢并想要保留的一件事是,如果我缩小它以至于它太小而无法完整显示两个列表视图,则列表框会缩小并自动添加滚动条,但无论如何按钮仍然可见。

在此处输入图像描述

但主要问题发生在列表视图大小不同时。他们将始终使用一半的可用空间。假设我有 10 只动物和 5 种蔬菜,我的窗户足够高,可以容纳 15 件物品。我希望蔬菜列表视图只要求它需要的空间,让动物列表视图要求所有剩余空间。相反,两个列表视图都要求 50% 的剩余空间,导致动物列表视图太小而蔬菜列表视图太大。

在此处输入图像描述

我认为我想要的是列表视图行在有足够空间时表现得像 Height="Auto" ,而在没有足够空间时表现得像 Height="*" 。

4

1 回答 1

1

为了得到你正在寻找的效果,我会做这样的事情:

<Window x:Class="GridDemo.SubWindow" x:Name="win"
        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 x:Name="grd">
        <Grid.RowDefinitions>
            <RowDefinition>
                <RowDefinition.Height>
                    <MultiBinding Converter="{StaticResource gpc}">
                        <MultiBinding.Bindings>
                            <Binding Path="Animals" />
                            <Binding ElementName="win" Path="ActualHeight" />
                        </MultiBinding.Bindings>
                    </MultiBinding>
                </RowDefinition.Height>
            </RowDefinition>
            <RowDefinition Height="Auto"/>
            <RowDefinition>
                <RowDefinition.Height>
                    <MultiBinding Converter="{StaticResource gpc}">
                        <MultiBinding.Bindings>
                            <Binding Path="Vegetables" />
                            <Binding ElementName="win" Path="ActualHeight" />
                        </MultiBinding.Bindings>
                    </MultiBinding>
                </RowDefinition.Height>
            </RowDefinition>
            <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>
</Window>

我使用了一个实现IMultiValueConverter来生成行高比例。它在一个资源字典中,键为“gpc”,实现如下:

public class GridProportionConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Count() == 2 && values[0] is ICollection && values[1] is double && ((ICollection)values[0]).Count > 0)
        {
            ICollection collection = (ICollection)values[0];
            double windowHeight = (double)values[1];

            if (windowHeight < 350)
            {
                return new GridLength(1, GridUnitType.Star);
            }

            return new GridLength(collection.Count, GridUnitType.Star);
        }

        return new GridLength(1, GridUnitType.Star);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我曾经ICollection假设您有某种ObservableCollection<T>收藏品。

我发现这工作得很好,但显然它依赖的一件事是每个ListViewItem人的高度大致相同ListView,否则你可能需要迎合高度差异。

我还设置了一些故障安全功能,如果窗口的高度低于某个值,则比例变为 1:1。

如果比例曾经失控,例如 300:1,您总是可以传入两个集合并基于此计算更合适的比例,例如,您可能会认为 4:1 是您可以容忍的最大差异,而您如果它变得更大,它会默认使用它。

于 2018-01-03T02:56:41.343 回答