Question Can a wrap panels children be aligned with each other?

glasswizzard

Well-known member
Joined
Nov 22, 2019
Messages
126
Programming Experience
Beginner
I have a wrappanel with several labels the user can enable or disable (collapse or make visible). When it wraps around, the labels on the second row aren't aligned with the labels above (because they aren't the same length).
Is there a way to get them to align with each other, so their centers are lined up?
 
Yes, yes it does, and this is the result one gets when the widths of the items don't match up...
Screenshot_1.png


Notice that the column widths are different. (I turned on GridLines to make it obvious how big each column is.)

XML:
<Window x:Class="Scratch.MainWindow"
        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:Scratch"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <TextBlock Text="Short" Grid.Row="0" Grid.Column="0" />
        <TextBlock Text="Long Passsage" Grid.Row="0" Grid.Column="1" />
        <TextBlock Text="Short Text" Grid.Row="0" Grid.Column="2" />
        <TextBlock Text="3" Grid.Row="1" Grid.Column="0" />
        <TextBlock Text="5" Grid.Row="1" Grid.Column="1" />
        <TextBlock Text="8" Grid.Row="1" Grid.Column="2" />

        <Grid.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="Margin" Value="5" />
                <Setter Property="HorizontalAlignment" Value="Center" />
                <Setter Property="VerticalAlignment" Value="Center" />
            </Style>
        </Grid.Resources>
    </Grid>
</Window>
 
How do you know how many columns could fit in the window at runtime? From post #27, won't the sum of the ActualWidth's be the same as the window width?

If another pair of text and number like {"Liverpool", 13} were to be added, how do you determine that another column definition could be added and still fit in the Window vs. determining that they should be a new row?

Although the XAML above had hardcoded the grid positions, recall that the original problem has the grid positions assigned dynamically.
 
From post #27, won't the sum of the ActualWidth's be the same as the window width?
Our OP wasn't adding just 3 columns like you. He wanted to fill up the window with controls, and the best way to do that is to use the Auto property. If you however just want to add 3 columns, you would be best using :
C#:
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>

There are other properties you can use, but you need to experiment with that yourselves to find what works for you guys. The result of changing the definition width is as follows :

Screenshot_61.jpg

If another pair of text and number like {"Liverpool", 13} were to be added, how do you determine that another column definition could be added and still fit in the Window vs. determining that they should be a new row?
Provide a code example for your question so I can understand what it is you're asking. Regarding : how do you determine that another column definition could be added and still fit in the Window?
This is why one of you needs to start writing a class to handle the actual windows size and to determine how many grid columns have been added and while doing so; you should ascertain whether or not you should use the Auto property or 1* or and to just use 1* for the last column added. 1* will fill the remaining space at the end of the last column.
Although the XAML above had hardcoded the grid positions, recall that the original problem has the grid positions assigned dynamically.
The Xaml above was for demonstration purposes to show how the structure would look. It makes very little sense to write out partial Xaml to of a partial structure when its the user who would be deciding how many controls are added to the window and not the developer. The Xaml shows that the Grid can be constructed to provide the intended structure without the need for stack panels and wrap panels currently. It is up to both of you to construct a class that can build this structure dynamically and apply it to a view. If you can do it in Xaml, you can do it dynamically. I said earlier in the topic that this would be a required step and that I would't be writing it due to time restraints and the fact that it's a lot of effort, lol but if you want to learn, its a great exercise Skydiver. Especially for future reference in case you're ever tasked by a client just as Sean Sexton was on his blog. ;)
 
Last edited:
Hello! Sorry for being away for so long, I went through some... stuff and ended up with a stress related illness, and it wasn't related to this topic! Honest :)

Before absorbing the posts that were made since then I just wanted to say I haven't run away and will be attempting to create a class to manage that grid. I'll be back soon.
 
Hope you are feeling better. Don't worry, @Sheepings and I have a side conversation regarding this, and we've also put it on hold for a bit while he's buried with work.
 
I've been trying desperately to resurrect this topic. I've just so much going on right now, I can barely breath with work, and both personal projects and new business ventures, I've not had time to commit myself to finishing writing out the Git on this one! I will get to it soon. I hope, and I also hope you are feeling better Glasswizzard. Welcome back!
 
I'm all better now, ready to rock and roll (y)

After thinking about trying to do this, I've decided to slightly simplify my goal initially, I'll use 50x50 buttons as the items in the grid, then I'll build up to using the textblocks, this way I can just use a constant 50 to begin with. Maybe that's easier, maybe it's not, I'm not sure, but it seems like it would be.

My initial thoughts on creating an app specifically to practice this are as follows (in terms of taking the first steps, I know this is not complete).
The GridManger class will contain fields such as the width/height of the items (50 in this simplified case, so I used a single Size field as opposed to two for width and height) which would translate I suppose as grid cell width and height, and the current number of columns and rows. This class will need to be able to access the width and height of the mainwindow (to know how many rows/columns there should be) and obviously the grid itself.

In the viewmodel having properties for the current width and height of the window seem necessary, not sure just yet what else would go here but I think it'll become apparent as I go on.

So from there I began to implement it and got stuck instantly :)

After binding the window size to the properties in the VM I made the GridManger class just as I described above and in the contructor I was going to call a method to set the number of columns and rows to be equal to the main windows size divided by 50. Maybe that's the wrong way to go about it, I don't know, but the GridManager class doesn't see the grid (MyGrid), I don't know how to resolve that and that's where I hit a wall and can't go further. My idea from there would have been to call that method again from the mainwindows resize event handler to do the same thing maintaining the right amount of rows/columns based on the window size. Or actually maybe that method call would be better placed in the VM's window width and height property setters.

I also had trouble referencing the VM's WindowHeight and WindowWidth properties from the GM. The only way I can think to let the GM class see the VM would be to pass a reference to it's contructor, but then it's scope would be restricted to the contructor, and that wouldn't be useful.

Handling scope is definitely my nemesis. I get the feeling I'm doing this quite wrong :)

Please don't feel any need to rush replies, I don't mind waiting.
 
Back
Top Bottom