WrapPanel 不包装在响应式容器中

WrapPanel does not Wrap in Reponsive Container

问题

所以,我有一个包含卡片动态列表的 WrapPanel,如您在此处所见。 出于美观原因,卡片会根据其内容(基本上是名称)的大小改变大小,并且所有卡片的大小都相同。

我希望能够在每张卡片中添加一个卡片列表,每个卡片显示几个关键字,例如这个。

我面临的问题是,无论我做什么,包含我的关键字的 WrapPanel 总是会使其父级扩展其宽度,而不是包装其内容。这实际上是非常合乎逻辑的,因为我不想为我的动态卡片使用“自动”尺寸以外的任何其他尺寸。但是我想知道如何阻止内部 WrapPanel 的这种行为,这样它就不会尝试扩展,而是使用他已有的地方并在需要时进行 Wrap。

我见过很多人要求类似的东西,但从来没有在动态控件中。

资源

这是创建我的主要卡片列表的控件:

<ItemsControl x:Name="FightersControl" Grid.IsSharedSizeScope="True">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="ColumnSize" />
                </Grid.ColumnDefinitions>
                <fight:FightingCharacterTileUserControl
                        Grid.Column="0" Grid.Row="0"
                        Margin="10"/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel  />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

这是创建我的关键字列表的控件:

<ItemsControl 
    ScrollViewer.HorizontalScrollBarVisibility="Disabled"
    ItemsSource="{Binding CustomVerboseStatusList.List}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:CustomVerboseStatusTile
                Margin="5"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel 
                Orientation="Horizontal"
            />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

我不会 post 我的完整卡片控制,因为它大约有 120 行,但这里是主要内容:

<Grid
    Margin="10, 0">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    ...

    <CustomStatusTile
        Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
    />
</Grid>

将大小设置为 WrapPanel。除非设置了宽度,否则它不知道要包装什么。这种或另一种方式必须在某处设置宽度,以便包裹面板停止增长。我认为如果您将固定大小设置为外部 Grid 它也会换行。

您当前的布局无法实现您想要的效果。

WPF 布局系统首先测量子项,然后在可视化树上反向工作。

因此,您的关键字 WrapPanel 是按其全宽测量的,最终决定了您的卡片的宽度。

一个解决方案是为卡片的根元素和关键字设置相同的最大宽度 WrapPanel

这可以让您的卡片变大,但您可以为宽度设置一个合理的上限,这将允许您的关键字在达到该限制时换行。

您可以将环绕面板的宽度绑定到其祖先的实际宽度之一。这将为环绕面板提供明确的宽度,这意味着 wpf 将根据需要限制其子级。事实上,它是数据绑定的,这使得包装面板可以根据需要响应大小变化。另见