WPF ListView项目以单独高度显示

时间:2017-09-18 08:05:43

标签: c# wpf listview

我目前正在尝试显示一个字典(它本身保存在字典中)。

我首先使用UniformGrid作为ItemsPanelTemplate,但实现得非常快,要显示的项目可以有各自的高度。

我到目前为止,我可以使用UniformGrid显示所有内容,但似乎无法使用Grid或StackPanel作为ItemsPanelTemplate。

下面的代码工作正常,其缺点是每个Operation-block都有相同的高度,尽管它们的高度可以变化。 经过一番思考后,我得出结论,StackPanel最好用,因为操作会显示彼此ble taking他们需要的高度。但是当我尝试时,我重新加入它们只占ListView高度的一小部分。

值得一提的是: Operation-UserControl本身确实评估其高度并相应地构建其布局。因此,它不占用显示所有内容所需的空间,而是显示适合可用空间的内容。

那么我如何才能实现ListViewItems(= operations)获取ListView的全高?

编辑:澄清
如果任何上述控制无法描述所描述的行为,但任何其他行为都可以提供所需的功能,请告诉我......

EDIT2:一些例子
总可用空间:500
没有滚动条。
旁注:没有maxItemLimit,但ItemCount极不可能超过10。

给出1个项目:(显示所有内容300所需的空间)
这个单项需要300个。

给出2个项目:(这些需要150和200个空间)
两个项目都将以全尺寸显示:150,200 (据推测只能使用StackPanel。)

给出10个项目:
那些10将被挤压为相同或相对于500中的完全所需尺寸(每个项目50个) 这两种行为都没问题。

UniformGrid vs StackPanel

<UserControl x:Name="vDay" x:Class="RefServiceClient.Day"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:local="clr-namespace:RefServiceClient"
        mc:Ignorable="d" 
        d:DesignHeight="60" d:DesignWidth="120"
        MinHeight="40">

<Grid x:Name="gridDay" 
      Width="{Binding ActualWidth, ElementName=vDay, Mode=OneWay}" 
      Height="{Binding ActualHeight, ElementName=vDay, Mode=OneWay}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Grid x:Name="DayHeader" Grid.Row="0">
        <!--containing header info: several textboxes, which are irrelevant for the question-->

        <TextBox x:Name="dayShortname"
                 Grid.Row="0" Grid.Column="1"
                 VerticalAlignment="Center"
                 HorizontalAlignment="Stretch"
                 Margin="1"
                 Text="{Binding Path=Value.DayShortname}"/>
    </Grid>

    <ListView x:Name="operations" Grid.Row="1" Background="Aqua"
              ItemsSource="{Binding Path=Value.OperationList}"
              HorizontalAlignment="Stretch"
              VerticalAlignment="Stretch"
              HorizontalContentAlignment="Stretch"
              VerticalContentAlignment="Stretch"
              ScrollViewer.HorizontalScrollBarVisibility="Disabled"
              ScrollViewer.VerticalScrollBarVisibility="Disabled">

        <ListView.ItemTemplate>
            <DataTemplate>
                <local:Operation Background="Crimson" VerticalContentAlignment="Stretch" VerticalAlignment="Stretch"/>
                <!--<local:Operation Background="Crimson" />-->
            </DataTemplate>
        </ListView.ItemTemplate>

        <ListView.ItemsPanel>
            <ItemsPanelTemplate>

                <!--<Grid Grid.IsSharedSizeScope="True"/>-->
                <!--<StackPanel/>-->
                <!--<VirtualizingStackPanel Orientation="Vertical"/>-->
                <UniformGrid Columns="1"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView>

</Grid>

2 个答案:

答案 0 :(得分:0)

您可以创建一个自定义面板,根据您的规则排列您的项目。然后你必须设计你的物品,使它们能够很好地显示它们可以承受的任何尺寸。

该小组的草图如下:

public class SqueezeStackPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        var desiredHeight = 0.0;
        foreach (UIElement child in InternalChildren)
        {
            child.Measure(availableSize);
            desiredHeight += child.DesiredSize.Height;
        }

        if (availableSize.Height < desiredHeight)
        {
            // we will never go out of bounds
            return availableSize;
        }
        return new Size(availableSize.Width, desiredHeight);
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        // measure desired heights of children in case of unconstrained height
        var size = MeasureOverride(new Size(finalSize.Width, double.PositiveInfinity));

        var startHeight = 0.0;
        var squeezeFactor = 1.0;
        // adjust the desired item height to the available height
        if (finalSize.Height < size.Height)
        {
            squeezeFactor = finalSize.Height / size.Height;
        }

        foreach (UIElement child in InternalChildren)
        {
            var allowedHeight = child.DesiredSize.Height * squeezeFactor;
            var area = new Rect(new Point(0, startHeight), new Size(finalSize.Width, allowedHeight));
            child.Arrange(area);
            startHeight += allowedHeight;
        }

        return new Size(finalSize.Width, startHeight);
    }
}

此面板可用于已禁用滚动条的ItemsPanelTemplate的{​​{1}}。

答案 1 :(得分:0)

这取决于。我会给你一个选择。第一。实现,比方说,Boolean AttachedProperty,标记这个特定实例是否应该具有一定的大小。如果0/1不够,请声明适当的枚举。第二。扩展现有的StackPanel,覆盖适当的受保护成员。至少,MeasureOverride / ArrangeOverride。在那里,您可以阅读相应附加属性的值,并确定它必须有多大或多小。这听起来像是一个解决方案吗?如果是这样,我可以提供一些例子。