如何切换 WPF 网格列可见性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1218332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:47:58  来源:igfitidea点击:

How to toggle a WPF Grid column visibility

wpfbindinggridgridsplittertogglebutton

提问by serialhobbyist

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:

我在我正在开发的 WPF 应用程序中使用它时遇到了一些麻烦。基本上,我所追求的是类似于 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.
  • 该应用程序在显示的主要部分具有三列。我需要在右侧有一列可调整大小。我认为这意味着将 Grid 与 GridSplitter 一起使用,但任何有效的方法都可以。
  • 我希望能够在应用程序关闭时保存右侧列的宽度并在应用程序打开时加载它,但这应该是初始大小:用户应该能够调整它的大小。
  • 当我调整窗口大小时,我希望左侧和右侧的列保持相同的大小,而中间列的大小随窗口宽度而调整。
  • 左侧和右侧的列需要具有最小宽度。当我调整右侧列的大小时,我希望中心列变小,而不是左侧列变小。
  • 我还希望能够使用列外的切换按钮切换右侧列的可见性,当它返回可见性时,我希望它与之前的宽度相同。

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

我正在尝试尽可能多地使用 XAML 和绑定。

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

我可以在上面放上奶油、冰淇淋和巧克力片吗?:-)

回答by Joel B Fant

As I read your requirements, instead of thinking of a Grid, I think of a DockPanel.

当我阅读您的要求时Grid,我想到的不是 a ,而是 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 middlewill change as rightis resized. If you resize the window, only middlewill change. Storing and setting the Widthof rightis up to you, but shouldn't be hard.

如果你想办法调整大小right,那么middle会随着right调整大小而改变。如果调整窗口大小,只会middle改变。存储和设置Widthofright由您决定,但应该不难。

As for allowing the user to resize right, that will a bit trickier, but I found this articlethat should help. This other articlemight help even more.

至于允许用户调整大小right,这会有点棘手,但我发现这篇文章应该会有所帮助。另一篇文章可能会提供更多帮助。

For the visibility of right, you can set its Visibilityto Collapsedto hide it and restore it by setting it to Visible.

对于 的可见性right,您可以将其设置VisibilityCollapsed以隐藏它并通过将其设置为 来恢复它Visible

Note: The panels inside don't have to be Grids, but you will want to use some sort of Panelfor each. Whatever you have inside your current Gridcolumns should work just fine.

注意:里面的面板不一定是Grids,但您需要Panel为每个面板使用某种类型。无论您在当前Grid列中拥有什么,都应该可以正常工作。

回答by Greg

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.

我将 Grid 与 GridSplitters 一起使用,因为这使得在保持左右列宽度的同时调整中间列的大小非常容易。

XAML:

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.

隐藏右列时,我只是将列宽设置为 0,因为网格列没有可见性属性。

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.

至于在启动时保存和恢复列宽,我只是将宽度变量存储到设置文件中,然后在您的应用程序重新打开时应用它们。

回答by Martin Schmidt

3 years later you can find another approach on CodeProject.

3 年后,您可以在 CodeProject 上找到另一种方法。

http://www.codeproject.com/Articles/437237/WPF-Grid-Column-and-Row-Hiding

http://www.codeproject.com/Articles/437237/WPF-Grid-Column-and-Row-Hiding

It adds a "Visible" property to custom Column definitions.

它将“可见”属性添加到自定义列定义。

回答by Jobi Joy

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.

将 columndefinition Width 设置为 Auto 并在该列内放置一个控件,并为其他列提供 Star 。每当您想隐藏包含内容的列时,请设置 control.Visibility=Collapsed 并且由于列宽为 Auto,您不会看到该列,其余列将占用空间。