WPF - Columns don't hide properly when GridSplitter is moved
Asked Answered
L

1

14

I'm trying to hide a column in a Grid with a GridSplitter when a button is clicked (the button sets the visibility of all items in the third column to collapsed). If I don't move the GridSplitter it works properly and the third column disappear, but if I move the GridSplitter the content disappear but the others columns don't resize to fill the empty space.

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

    <Grid.ColumnDefinitions>
        <ColumnDefinition x:Name="a" Width="*"/>
        <ColumnDefinition x:Name="b" Width="3"/>
        <ColumnDefinition x:Name="c" Width="Auto" MaxWidth="600"/>
    </Grid.ColumnDefinitions>
    <Border Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" Background="Green">
        <Image Source="te/Dante.png" Height="Auto" Margin="0,128,2,71"/>
    </Border>
    <Button Grid.Column="0" Grid.Row="0" Width="30" Height="30" Margin="0,10,10,0" HorizontalAlignment="Right" VerticalAlignment="Top" Click="Button_Click"></Button>
    <GridSplitter Width="5" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" ResizeDirection="Columns" HorizontalAlignment="Left" Background="White" BorderBrush="Black" BorderThickness="1,0" ResizeBehavior="PreviousAndCurrent"/>
    <WrapPanel x:Name="wpC" Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" MinWidth="300" HorizontalAlignment="Stretch" Background="Aqua" Panel.ZIndex="-1"></WrapPanel>
</Grid>

Here is an example of my problem (gif):

How can i solve this problem? Possibly respecting MVVM pattern.

Leonardoleoncavallo answered 4/5, 2016 at 11:6 Comment(2)
Show how exactly you hide something? Using x:Name is already not pure MVVM (I am assuming you are setting column definition width in code behind). Btw, you can use ScreenToGif and capture few frames to demonstrate issue, see my question.Markup
i've added the gif, up to now i made a solution using code behind. i would like to know if there is a way to solve this problem without using code behindLeonardoleoncavallo
M
14

The problem is simple, you set GridSplitter ResizeBehavior="PreviousAndCurrent", but previous grid column width is * and as soon as you move splitter its width units will be changed to absolute (so it will not be able to resize when 3d column width is changed).

Simply set GridSplitter ResizeBehavior="PreviousAndNext" to solve the problem. If you do so the splitter will modify width of 3d column, but shouldn't touch first one anymore.

Btw, instead of using button and click event you can utilize ToggleButton (which IsChecked is bound to Visibility of container with content you want to hide), see this answer. Using converters with pure xaml view is better MVVM than the one with some code behind and x:Name.


Right, you have few layout problems, here is a complete solution:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <Border Background="Green" />
    <ToggleButton x:Name="toggleButton"
                  Width="30"
                  Height="30"
                  Margin="0,10,10,0"
                  HorizontalAlignment="Right"
                  VerticalAlignment="Top" />
    <Grid Grid.Column="1"
          Visibility="{Binding IsChecked, ElementName=toggleButton, Converter={StaticResource BooleanToVisibilityConverter}}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="300"
                              MinWidth="300"
                              MaxWidth="600" />
        </Grid.ColumnDefinitions>
        <GridSplitter Width="5"
                      ResizeBehavior="CurrentAndNext" />
        <WrapPanel Grid.Column="1"
                   Background="Aqua" />
    </Grid>
</Grid>

No need for code-behind, get converter from here.

Point are: 1) put splitter inside hide-able container 2) setup grid columns to have * and fixed width (splitter doesn't work well with auto columns).

Demo:

Markup answered 4/5, 2016 at 14:37 Comment(3)
i setted ResizeBehavior to PreviousAndNext but it doesn't solve the problem. it seems that the 3rd column width change from Auto to a value and that value is kept even if the Visibility is setted to Collapsed. I tried other ResizeBehavior but nothing works.Leonardoleoncavallo
i'd never thought of turning this originally obvious 3 columns (or 3 rows) into nested ones this way. this is so much easier than other things i was trying to do!Bricky
Thank you for helping me with the same issue (but with rows). Seems like there are many ways to attempt this, but this is much the cleanest solution (and not exactly obvious!)Papism

© 2022 - 2024 — McMap. All rights reserved.