C# WPF:如何在控件大小中正确使用多个列表视图?
这是我现在的XAML: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"
<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)}
的内容(我将它放在windowHeightif
块之后,它似乎工作得很好)。
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();
}
}