Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to toggle a WPF Grid column visibility

I'm having some trouble getting this to work in a WPF app I'm working on. Basically, what I'm after is something like the Task pane in an MMC:

  • The app has three columns in the main part of the display. I need a column on the right side which is resizable. I presume this means using a Grid with a GridSplitter but anything that works will do.
  • I want to be able to save the width of the right-side column when the app is closed and load it when the app is opened but this should be an initial size: the user should be able to resize it.
  • When I resize the window, I want the left- and right-side columns to stay the same size and the middle column to resize with the window width.
  • The left- and right-side columns need to have a minimum width. When I resize the right-side column I want the centre column to get smaller but not the left-side column.
  • I also want to be able to toggle the visibility of the right-side column with a toggle button which is outside the column and when it returns to visibility I want it to be the same width it was before.

I'm trying to do as much as possible in XAML and with binding.

And can I have it topped with cream, ice cream and chocolate chips, please? :-)

like image 845
serialhobbyist Avatar asked Aug 02 '09 07:08

serialhobbyist


People also ask

How do you make grid lines visible in WPF?

First Method: By typing XAML Code ColumnDefinitions property. By default, GridLines are invisible. For showing the GridLines, set the ShowGridLines property of the Grid to True.

How do I hide the grid in WPF?

The gridlines can be hidden by setting the ShowGridLines property of ChartArea Class to False in ChartAxis tag. The following code illustrates this. The ultimate WPF UI toolkit to boost your development speed.

How do I hide grid rows?

In the Report Designer, select a row or a column in a grid. In Row Properties or Column Properties, select Hide Always. Specify whether ignore the values or calculations in the hidden row or column when you print or view a report.


2 Answers

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 Grids, but you will want to use some sort of Panel for each. Whatever you have inside your current Grid columns should work just fine.

like image 92
Joel B Fant Avatar answered Oct 06 '22 00:10

Joel B Fant


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.

like image 25
Greg Avatar answered Oct 05 '22 23:10

Greg