WPF:如何正确使用控件大小的多个列表视图?

时间:2018-01-02 23:13:14

标签: c# wpf xaml listview wpfgrid

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

当我跑步时,它会显示:

enter image description here

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

我喜欢和想要保留的是,如果我缩小它以使其太小而不能完整地显示两个列表视图,则列表框会缩小并自动添加滚动条,但按钮保持可见无论如何。

enter image description here

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

enter image description here

我认为我想要的是列表视图行的行为类似于Height =&#34; Auto&#34;当它们有足够的空间时,表现得像Height =&#34; *&#34;什么时候没有。

1 个答案:

答案 0 :(得分: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的实现来生成行高比例。它位于资源字典中,其键为&#34; gpc&#34;并按如下方式实施:

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是你最大的差异&#39 ; d容忍,如果它变得更大,你就会默认。