How to toggle a WPF Grid column visibility
As I read your requirements, instead of thinking of a Grid
, I think of a DockPanel
.
<DockPanel> <Grid Name="right" DockPanel.Dock="Right" MinWidth="100" /> <Grid Name="Left" DockPanel.Dock="Left" MinWidth="100" /> <Grid Name="middle" /></DockPanel>
If you make a way to resize right
, then middle
will change as right
is resized. If you resize the window, only middle
will change. Storing and setting the Width
of right
is up to you, but shouldn't be hard.
As for allowing the user to resize right
, that will a bit trickier, but I found this article that should help. This other article might help even more.
For the visibility of right
, you can set its Visibility
to Collapsed
to hide it and restore it by setting it to Visible
.
Note: The panels inside don't have to be Grid
s, but you will want to use some sort of Panel
for each. Whatever you have inside your current Grid
columns should work just fine.
I used a Grid with GridSplitters since this made it really easy to resize the middle column while maintaining the widths of the left and right columns.
XAML:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="MainWindow" Title="Main Window" Width="640" Height="480"> <Grid> <Grid.ColumnDefinitions> <!-- Left column --> <ColumnDefinition Width="200" MinWidth="100"/> <!-- Left GridSplitter column --> <ColumnDefinition Width="5"/> <!-- Center column. A width of * means the column will fill any remaining space. --> <ColumnDefinition Width="*"/> <!-- Right GridSplitter column --> <ColumnDefinition x:Name="RightSplitterColumn" Width="5"/> <!-- Right column --> <ColumnDefinition x:Name="RightColumn" Width="200" MinWidth="100"/> </Grid.ColumnDefinitions> <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> <GridSplitter Grid.Column="3" HorizontalAlignment="Stretch" /> <Button x:Name="ToggleButton" Grid.Column="2" Content="Toggle Right Column" Width="150" Height="25" Click="ToggleButton_Click" /> </Grid></Window>
Code-Behind
When hiding the right column, I just set the column width to 0 since grid columns don't have a visibility property.
public partial class MainWindow : Window{ private double rightColumnWidth; private double rightColumnMinWidth; private bool rightColumnHidden; public MainWindow() { this.InitializeComponent(); } private void ToggleButton_Click(object sender, RoutedEventArgs e) { if (rightColumnHidden) { // Restore the widths. RightColumn.MinWidth = rightColumnMinWidth; RightColumn.Width = new GridLength(rightColumnWidth); RightSplitterColumn.Width = new GridLength(5); } else { // Remember the user-set widths for the columns. rightColumnWidth = RightColumn.Width.Value; rightColumnMinWidth = RightColumn.MinWidth; // Remember to set the minimum width to 0 before changing the actual // width. RightColumn.MinWidth = 0; RightColumn.Width = new GridLength(0); RightSplitterColumn.Width = new GridLength(0); } rightColumnHidden = !rightColumnHidden; }}
As for saving and restoring the column widths on startup, I would just store the width variables to a settings file and then apply them when your app is reopened.
Set the columndefinition Width to Auto and put a control inside that column and give Star for the other columns . Whenever you want to hide the column with content, set the control.Visibility=Collapsed and since column width is Auto, you wont see that column and the remaining columns will take the space.