如何在WPF中自动设置ItemsControl的高度?

7

我在WPF中使用了ItemsControl,将字典集合作为ItemsControl的ItemsSource。在这个字典集合中,使用了键和ObservableCollection。每个字典项的ObservableCollection中有不同的项目,所以当我提供一个ItemsSource时,它们将具有相同的高度。

代码如下:

 <ItemsControl
            Grid.Row="1"
            Height="Auto"
            ItemsSource="{Binding Values}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel
                        HorizontalAlignment="Stretch"
                        VerticalAlignment="Top"
                        IsItemsHost="True"
                        Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <GroupBox
                        MinWidth="303"
                        Margin="5,0,0,0">
                        <ItemsControl Margin="20,5,0,5">
                            <ItemsControl.Resources>
                                <CollectionViewSource x:Key="Collection" Source="{Binding Value}" />
                                <DataTemplate DataType="{x:Type Model:Sensor}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto" />
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="*" />
                                        </Grid.ColumnDefinitions>
                                        <Label
                                            Grid.Column="1"
                                            Content="{Binding Name}"
                                            FontFamily="SegoeUI-Semibold"
                                            FontSize="12"
                                            FontWeight="SemiBold" />
                                        <Label
                                            Grid.Column="2"
                                            HorizontalContentAlignment="Center"
                                            Content="{Binding Value}"
                                            FontFamily="SegoeUI"
                                            FontSize="12" />
                                    </Grid>
                                </DataTemplate>

                                <DataTemplate DataType="{x:Type Model:DigitalInput}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto" />
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="*" />
                                        </Grid.ColumnDefinitions>
                                         <Label
                                            Grid.Column="1"
                                            Content="{Binding Name}"
                                            FontFamily="SegoeUI-Semibold"
                                            FontSize="12"
                                            FontWeight="SemiBold" />
                                        <Label
                                            Grid.Column="2"
                                            HorizontalContentAlignment="Center"
                                            Content="{Binding InputState}"
                                            FontFamily="SegoeUI"
                                            FontSize="12" />
                                    </Grid>
                                </DataTemplate>
                            </ItemsControl.Resources>
                            <ItemsControl.ItemsSource>
                                <CompositeCollection>
                                    <CollectionContainer Collection="{Binding Source={StaticResource Collection}}" />
                                </CompositeCollection>
                            </ItemsControl.ItemsSource>
                        </ItemsControl>
                    </GroupBox>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

请查看类代码:

 private Dictionary<string, ObservableCollection<IValue>> values;
 public Dictionary<string, ObservableCollection<IValue>> Values
    {
        get { return values; }
        set { values = value; }
    }

当前输出: enter image description here 期望的输出: enter image description here 我需要将项目分组,以达到期望的输出效果,请问您能否提供任何解决方案?


1
最终我找到了StaggeredPanel的源代码。请看我的回答。 - Access Denied
2个回答

2
这就是WrapPanel的工作原理。如果你设置了水平方向,一行中的所有项都将具有相同的高度,并且元素将换行到下一行。 你可以尝试为WrapPanel指定Orientation="Vertical",但不确定是否适合你。在这种情况下,列中的所有元素将具有相同的宽度。
否则,您既不需要WrapPanel也不需要UniformGrid,您需要一个名为StaggeredPanel的不同面板。 uwp的源代码可以很容易地在WPF中使用,我刚刚检查了一下。只需要重写一行代码,这并不是什么大问题,具体请参见答案RegisterPropertyChangedCallback(Panel.HorizontalAlignmentProperty, OnHorizontalAlignmentChanged); 类似控件的说明可以在codeproject上找到(称为VariableSizedWrapGrid)。但是我检查过它,它有错误。

在iOS上,它称为马赛克视图或Android上的RecyclerView的StaggeredLayoutManager。


1
我有一个可调整大小的面板在包装面板内。因此,用户可以调整包装面板内的面板大小。当拖放另一个可调整大小的面板时,它将对齐剩余空间。 - Achu_L
终于找到了更好的StaggeredPanel代码。 - Access Denied

1

尝试使用 UniformGrid,而不是 WrapPanel

<UniformGrid Columns="1" IsItemsHost="True" />

还有,我对于Height="Auto"设置不确定。请将其删除。该设置属于网格的RowDefinition


1
那么你的意思是想要最小化项目之间的间距?听起来像是一个装箱问题。你可能需要创建一个带有自定义逻辑的自定义面板来解决这个问题。 - l33t
我有一个固定大小的空间,需要用可变数量的元素进行均匀填充。这段代码正好可以实现这一功能。 - AyCe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接