C# WPF:如何在控件大小中正确使用多个列表视图?

C# WPF:如何在控件大小中正确使用多个列表视图?,c#,wpf,xaml,listview,wpf-grid,C#,Wpf,Xaml,Listview,Wpf Grid,这是我现在的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"

这是我现在的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>

当我运行时,它显示以下内容:

问题马上就来了,它占用了太多的垂直空间

我喜欢并希望保留的一件事是,如果我缩小它,使其太小,无法完整显示两个ListView,则ListBox会缩小并自动添加滚动条,但无论发生什么情况,按钮都会保持可见

但是,当列表视图的大小不同时,主要问题就会出现。他们将始终使用一半的可用空间。假设我有十只动物和五种蔬菜,我的窗户足够高,可以放15样东西。我希望蔬菜列表视图只要求它所需的空间,让动物列表视图要求所有剩余空间。相反,这两个listview都会占用剩余空间的50%,导致动物listview太小而蔬菜listview太大


我认为我希望listview行在有足够空间时表现得像Height=“Auto”,在没有空间时表现得像Height=“*”。

要获得您想要的效果,我会这样做:

<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>
我使用了
ICollection
假设您的收藏有某种
observedcollection

我发现这很有效,但很明显,这取决于每个
列表视图项在每个
列表视图中的高度大致相同,否则您可能需要考虑高度差异

我还加了一点故障保险,如果窗户的高度低于某个值,比例就会变成1:1


如果比例失控,例如300:1,您可以始终传入两个集合,并在此基础上计算更合适的比例,例如,您可能会认为4:1是您可以容忍的最大差异,如果它变得更大,您会默认为4:1。

您是否尝试过使用
Height=“Auto”
并将
MaxHeight
设置为
RowDefinition
ListView
?谢谢!不过有新的问题。我将其添加到XAML SizeToContent=“Height”中,现在窗口开始的大小正确了。但在我调整窗口大小之前,比例无法正确调整。在不改变转换器的情况下演示这一点的最简单方法是从0只动物和20种蔬菜开始。加载表单,listview1几乎完全折叠。开始调整大小,listview1立即增长到20px左右。(有没有更好的方法问后续问题?我有一个更好的例子,通过代码,但我不想摆脱原来的问题)我不确定这两种方法是否兼容。如果您返回到两者的硬编码
*
,您将看到它也不会注意到这一点(直到您调整窗口大小)。您可以尝试向转换器添加类似
if(collection.Count<3){returnnewgridlength(100,GridUnitType.Pixel)}
的内容(我将它放在windowHeight
if
块之后,它似乎工作得很好)。
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();
    }
}