0

Problem

So, I have a WrapPanel that contains a dynamic list of cards such as you can see here. The cards change size according to the size of their content (basically the name) and all cards have the same size, for aesthetic reasons.

The card List

I would like to be able to add a list of cards inside each card displaying a few keyword each such as this.

A Card with Status

The problem I face, is that no matter what I do, the WrapPanel that contains my keywords will always make its parent extend its Width, instead of wrapping its content. It actually is quite logic as I don't want to use anything else than "Auto" sizes for my dynamic cards. But I'd like to know how to block this comportement for the inner WrapPanel, so that it does not try to extend, but use the place he already has and Wrap if required.

I've seen many people asking for similar thing, but never in a dynamic Control.

Resources

This is the Control that creates my list of main Cards:

<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>

This is the Control that creates my list of keywords :

<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>

I won't post my complete Card Control as it's around 120 lines, but here is the main thing:

<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>
Community
  • 1
  • 1
Angevil
  • 469
  • 3
  • 10

3 Answers3

1

you can bind the wrap panel's width to one of its ancestors' actual widths. this will give the wrap panel an explicit width, meaning wpf will constrain its children as desired. the fact that it's data-bound simply makes the wrap panel responsive to size changes, also as desired. see also https://stackoverflow.com/a/1627811/4868864

Kirk Horton
  • 368
  • 1
  • 7
0

Set the size to WrapPanel. It will not know what to wrap unless it has width set up on it. This way or another a width has to be set up somewhere so the wrap panel stops growing. I think if you set fixed size to outer Grid it will also wrap.

Robert
  • 2,407
  • 1
  • 24
  • 35
  • The thing is, I don't want to use a fixed size, as my card will vary in size depending on the name of the characters I bind to the Card :/ – Angevil Feb 12 '20 at 15:16
  • @Angevil you can bind the wrap panel's width to one of its ancestors' actual widths. this will give the wrap panel an explicit width, meaning wpf will constrain its children as desired. the fact that it's data-bound simply makes the wrap panel responsive to size changes, also as desired. see also https://stackoverflow.com/a/1627811/4868864 – Kirk Horton Feb 12 '20 at 17:14
  • Thanks @KirkHorton, I'm gonna check this out asap :) – Angevil Feb 12 '20 at 18:12
  • @KirkHorton It just works like a charm :) if you mind to write this in an answer, I shall mark it so. – Angevil Feb 12 '20 at 19:21
0

It's impossible to achieve what you are wanting to do with your current layout.

The WPF layout system measures children first and works backwards up the visual tree.

Because of this, your Keyword WrapPanel is measured to its full width and that ends up determining how wide your card is.

One solution is to set the same MaxWidth for your card's root element as well as your keyword WrapPanel.

This allows your cards to grow in size, but you set a reasonable upper limit to the width, which will allow your keywords to wrap when they get to that limit.

Keithernet
  • 2,349
  • 1
  • 10
  • 16