如何切换 WPF Grid 列的可见性

Posted

技术标签:

【中文标题】如何切换 WPF Grid 列的可见性【英文标题】:How to toggle a WPF Grid column visibility 【发布时间】:2010-11-16 03:25:01 【问题描述】:

我无法在我正在开发的 WPF 应用程序中使用它。基本上,我所追求的是类似于 MMC 中的任务窗格:

该应用程序在显示的主要部分有三列。我需要在右侧有一个可调整大小的列。我认为这意味着将 Grid 与 GridSplitter 一起使用,但任何可行的方法都可以。 我希望能够在应用关闭时保存右侧列的宽度,并在应用打开时加载它,但这应该是初始大小:用户应该能够调整它的大小。李> 当我调整窗口大小时,我希望左侧列和右侧列保持相同大小,并且中间列随着窗口宽度调整大小。 左侧和右侧的列需要具有最小宽度。当我调整右侧列的大小时,我希望中心列变小,但不是左侧列。 我还希望能够使用列外的切换按钮切换右侧列的可见性,当它返回可见性时,我希望它与之前的宽度相同。

我正在尝试在 XAML 和绑定中做尽可能多的事情。

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

【问题讨论】:

我对原始问题进行了大量编辑,因为我的原始问题像泥巴一样清晰。 十分钟后我的第二次赏金。由于我还没有完成一个,我不太确定会发生什么。我想我们会看到...... 如果你没有选择一个投票最高的答案会自动得到它 如果使用自动选择,回答者只能获得一半的赏金。自动选择也仅在赏金时间用完且未选择任何答案时才会发生。 【参考方案1】:

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

【讨论】:

我无法让它与所需的行为一起工作。将 Width 设置为 Auto 意味着调整窗口的大小会以对用户来说不合理的方式影响列。【参考方案2】:

当我阅读您的要求时,我没有想到 Grid,而是想到了 DockPanel

<DockPanel>
    <Grid Name="right"
        DockPanel.Dock="Right" MinWidth="100" />
    <Grid Name="Left"
        DockPanel.Dock="Left" MinWidth="100" />
    <Grid Name="middle" />
</DockPanel>

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

至于允许用户调整right 的大小,这会有点棘手,但我发现this article 应该会有所帮助。 This other article 可能会有所帮助。

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

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

【讨论】:

我使用了你的方法和你建议的文章,它就像一个魅力。我将内容和拆分器的可见性属性绑定到切换按钮,所有工作都按计划进行。非常感谢您的帮助。【参考方案3】:

我使用了 Grid 和 GridSplitters,因为这样可以很容易地调整中间列的大小,同时保持左右列的宽度。

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>

代码隐藏

隐藏右列时,我只是将列宽设置为 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;
    

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

【讨论】:

感谢您的建议:它确实实现了我想要的,所以我已经“升级”了它,但我认为这种事情最好在 XAML 中完成,并尽可能进行绑定。我接受了乔尔的回答,因为它更接近这种方法。再次感谢您的工作。【参考方案4】:

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

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

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

【讨论】:

以上是关于如何切换 WPF Grid 列的可见性的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义 wpf 控件上绑定数据网格列的可见性?

WPF 边框子可见性无效

在 WPF 中动态更改网格的可见性

WPF 可见性折叠保留空间

WPF:尝试根据组合框中的选择更改可见性

XAML 在多个选项之间切换可见性