wpf - Grid column not filling remaining space when

2019-06-24 06:28发布

问题:

I've got a grid with 3 columns: the first has its Width set to "*", which I have been led to believe will make it fill up any remaining space left by the other columns. The second has a width of 8, and the third's Width is set to "Auto" so its size changes depending on its contents.

In my 2nd column I have a GridSplitter, so that when dragged I can change the width of both the first and third columns. This works fine, the issue is that I have a grid in my third column that, when toggled, will have its visibility set to collapsed. When collapsed, I need the first column to fill all of the remaining space. I tried to do this many ways:

  • Set HorizontalAlignment on first column to Stretch
  • Bound the Grid.Rowspan of the first column to the visibility of the third one, so that when when hidden the Rowspan will change to 3 and, since its width is using "*", it should theoretically use all of the available space in all 3 columns.

The weird thing is that, if I do not resize the columns using the GridSplitter, then the first column will fill all remaining space properly. Yet after resizing, the first column will not budge. It's almost as if, when dragging the GridSplitter to resize the columns, WPF change the width of both columns to become absolute instead of their star and auto values, making it so they will not fill the space after a resize.

XAML Code (condensed) as requested:

<Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
    <Grid x:Name="AssetListViewGrid" Grid.Column="0" Grid.RowSpan="{Binding Visibility, ElementName=AssetViewMetadataSplitter, Converter={StaticResource SplitterVisibilityToRowSpanConverter}}"  Margin="0 4 0 4">
    <!-- irrelevant code -->
    </Grid>
<GridSplitter x:Name="AssetViewMetadataSplitter" Grid.Column="1" Opacity="0.8" HorizontalAlignment="Center" Width="6" Margin="3 5 1 5" ToolTip="Grab to resize" Visibility="{Binding IsChecked, ElementName=GridHeaderVisibilityToggleButton, Converter={StaticResource VisConverter}}"/>
<Grid x:Name="MetadataGrid" Margin="4 2 4 2" Grid.Column="2" DataContext="{Binding MetadataViewModel}" Visibility="{Binding IsChecked, ElementName=GridHeaderVisibilityToggleButton, Converter={StaticResource VisConverter}}">
    <!-- irrelevant code -->
</Grid>

回答1:

I just ran into this as well. In my app it seemed that a GridSplitter was in fact changing the width values to absolute instead of * also, so I'm guessing that is the behavior.

I ended up using code-behind to solve it. First, name column 1:

<ColumnDefinition Width="*" x:Name="Column1"/>

Then, add an event handler for when your MetadataGrid visibility changes, & call this code to reset Column1 to a * width to fill the rest:

Column1.Width = new GridLength(1, GridUnitType.Star);

You might also try doing something in the XAML with style triggers to reset the Column1 width to * based on the MetadataGrid's visibility state. My case was much more complex with custom sizes & varied conditions & expanders, so I used code-behind, so I'm not sure if xaml triggers would work for yoU or not . Hopefully that helps though.