如何切换WPF网格列的可见性

15

我在一个WPF应用程序中遇到了一些问题,希望你能帮忙。基本上,我想要的是类似MMC中任务窗格的东西:

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

我尝试尽可能多地使用XAML和绑定来完成。

还可以在顶部加上奶油、冰淇淋和巧克力碎片吗? :-)


我已经对原问题进行了大幅编辑,因为我的原始问题非常不清楚。 - serialhobbyist
我在十分钟内获得了第二个赏金。由于我还没有完成任何一个,所以我不太确定会发生什么。我想我们等着瞧吧... - serialhobbyist
如果你不选择一个,最高投票的答案会自动得到它。 - Preet Sangha
使用自动挑选答案的话,回答者只能得到悬赏金额的一半。而且,只有在悬赏计时结束且没有选择答案的情况下才会触发自动挑选答案。 - Joel B Fant
4个回答

17

根据您的需求,我认为不要考虑使用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 会改变。存储和设置 right 的宽度取决于您,但不应该很难。
至于允许用户调整 right 的大小,这将有点棘手,但我找到了这篇文章可能会有所帮助。这篇文章可能会更有帮助。
对于 right 的可见性,您可以将其 Visibility 设置为 Collapsed 来隐藏它,并通过将其设置为 Visible 来恢复它。
注意:内部的面板不一定是 Grid,但每个面板都需要使用某种 Panel。您当前 Grid 列中的任何内容都应该可以正常工作。

我使用了你提出的方法和建议的文章,效果非常好。我将内容和分隔条的可见性属性与切换按钮绑定,一切都按计划进行。非常感谢你的帮助。 - serialhobbyist

8

我使用了带有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 中尽可能使用绑定来完成。我接受了 Joel 的答案,因为它更接近那种方法。再次感谢您的工作。 - serialhobbyist

4

4

将columndefinition的宽度设置为自动,并在其中放置一个控件,为其他列设置星号。每当您想隐藏具有内容的列时,将control.Visibility = Collapsed设置为,由于列宽为自动,您将看不到该列,剩余的列将占据空间。


我无法使其按预期行为工作。将宽度设置为自动意味着调整窗口大小会以对用户来说看起来毫无意义的方式影响列。 - serialhobbyist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接