1

I'm wanting to limit a Grid.ColumnDefinition to a maximum width but I do not know the width to do this programatically. Consider the following XAML:

   <Grid MaxWidth="150" HorizontalAlignment="Left">
      <Grid.ColumnDefinitions>
         <ColumnDefinition Width="Auto" />
         <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      
      <Grid.RowDefinitions>
         <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>

      <TextBlock Grid.Column="0" Text="A" TextWrapping="Wrap" Background="LightGreen"  />
      <TextBlock Grid.Column="1" Text="B" TextWrapping="NoWrap" Background="LightSteelBlue" />      
   </Grid>

The Grid is 150px wide at most but can be less. The TextBlock in column 0 is Wrap. The TextBlock in column 1 is NoWrap. Background colors added simply for clarity. Result:

enter image description here

Now let's change the text:

      <TextBlock Grid.Column="0" Text="I'm long but I wrap" TextWrapping="Wrap" Background="LightGreen"  />
      <TextBlock Grid.Column="1" Text="I'm a long single line" TextWrapping="NoWrap" Background="LightSteelBlue" />      

Result:

enter image description here

The wrappable text does not wrap. Seems no feedback is provided from the Grid to the TextBlock. The behavior I want is for the Grid to realize that its columns being Auto have expanded past its own MaxWidth property and attempt to shrink the contents in the columns. The TextBlock that is NoWrap won't abide by this request while the TextBlock with Wrap would. Hence the output would be:

enter image description here

I can't figure out a way to do this with any * sizing since I don't want the grid to take this much space unless the contents are needed. Incidentally the actual Grid has many columns of many potential sizes. This is a shortened example.

[Edit]: My solution is a hack and I don't care for it, but it works. I created a property on my model which determines the content that can appear in other columns including images, margins, text, etc. Then it subtracts from the grid size to find a maximum width for a TextBlock which has Wrap set. Works just fine but is ugly as can be.

Paul
  • 5,700
  • 5
  • 43
  • 67
  • Set the first width of the first `ColumnDefinition` to `*` and the second to `Auto`? What's the problem with this? – mm8 Aug 25 '21 at 14:10
  • The first column is then huge. I don't want * size. – Paul Aug 26 '21 at 13:52
  • How can the first column be huge when the `Grid` has a `MaxWidht` of 150...? Your issue is unclear. – mm8 Aug 26 '21 at 17:32
  • Look at the screenshots above. While they are just an example, the "AB" is what I want. If the A were star sized it would be "A [130px or so] B". First I want B to take all the space it needs. Second, I want A to take all the space it needs up to the point at which the grid size maxes out and then A should wrap. I solved this with ugly hacky code as mentioned already. But I had hoped there was a more elegant XAML solution. – Paul Aug 26 '21 at 18:04

1 Answers1

2

Although Auto does not work well for you, doing the * can work wonders. Instead of just a blind-eye to * for all other columns, you can do [a numeric value]*, like Width="120*" which will allocate the 120, but, if there is more room, it will get the rest.

Now, that said, if you have SOME columns that you know would be fixed, like some date field which is always 100 width, or some string type category of 1 character, maybe a fixed width of 10, but the rest are otherwise flexible. Just blend them something like

Width 100
Width 10
Width 500*
Width 250*

So, if your screen has available width of 1200, columns 1 and 2 will remain at their fixed widths. However, the 500* and 250* will get their baseline width and then equally split the remaining width between them. The more "*"-based columns to split the widths, they all split the available space.

Have you tried doing something like that?

Vultuxe
  • 87
  • 9
DRapp
  • 47,638
  • 12
  • 72
  • 142
  • This is the same as doing 2* and * since the ration is 2:1. But star sizing is not appropriate for me. The columns should not grow unless needed. If the 500* column contains "A" and the 250* column contains "B" this creates massive white space between "A" and "B" and is the entire purpose of auto-sizing and trying to force a wrap. What I really want is `Width="Auto" MaxWidth="*"` meaning "Grow as much as needed but only up to the available space. – Paul Aug 25 '21 at 13:17
  • @Paul, gotcha, and suspected as much, but now the tough call. You display 20 rows of data in the grid. Some have alternating short and long context between columns A and B... who wins. Each row wont be dynamically sized just for itself. That would be a mess for someone's eyes to focus on. Sometimes a pre-gauge estimate on spacing might be more appropriate even if percentage simulation 40* and 60* for two columns. – DRapp Aug 25 '21 at 13:20