【问题标题】:Collapse 'button' for splitcontainer control折叠容器控制的“按钮”
【发布时间】:2011-06-16 23:37:09
【问题描述】:

我在我的 WinForms 桌面应用程序中使用 Microsoft 的 SplitContainer 控件。

我想在拆分器控件的面板之间有一个小按钮(或任何漂亮的 UI 元素)来折叠其中一个面板。例如。一个包含两个部分的“按钮”,如果我单击一个部分,右侧面板会折叠,如果我单击另一部分,则左侧面板会折叠。

这可能吗?怎么可能实现?

【问题讨论】:

标签: c# .net winforms visual-studio-2010 splitcontainer


【解决方案1】:

您必须为此编写自己的事件。你必须决定设计。希望您需要以下内容。

private void radButton1_Click(object sender, EventArgs e) 
{ 
    splitPanel1.Collapsed = !splitPanel1.Collapsed; 
}

编辑 1

没有你想的那么简单。看看herehere 了解一下。

编辑 2

您可以在 Dock:Top 的两个面板中添加两个工具条,并添加两个按钮,如下图所示,看起来不错。只是一个想法......

编辑3

Splitter 是您的另一种选择。 看看here

【讨论】:

  • 谢谢,我的主要问题是关于 UI 设计。我希望有一个简单的解决方案来显示这种按钮。我在几个 UI 上看到过它,但我看到 MS splitcontainer 没有将它作为内置功能。
  • @Keller Zoltam:不幸的是,没有这么简单的方法。有关详细信息,请参阅我的编辑。
  • @Keller Zoltam :是的,非常失望。你一定从一些第三方控件库中看到过这样的控件,但是 VS 标准的 SplitContainer 没有。
【解决方案2】:

我在我的实现中使用了这个解决方案,对你来说可能为时已晚,但可能会帮助其他人。

在我的实现中,我还将控件从一个面板移动到另一个面板,这就是为什么我只将面板折叠状态更改为最后一个操作。

由于我不能发图片,请按照下图([] 为按钮)尝试一下:

 ╔════════════╤═════════════╗
 ║         [<]│[>]          ║ 
 ║            │             ║ 
 ║            │             ║ 
 ║            │             ║ 
 ║            │             ║ 
 ║            │             ║ 
 ╚════════════╧═════════════╝

以下是左侧面板(panel1)的实现,右侧面板也使用了类似的功能。

    private void setSplitterLeftPanelCollapsedState(bool collapse)
    {
        splitContainer1.SuspendLayout();

        // Collapse the left panel
        if (collapse)
        {
            if (!splitContainer1.Panel1Collapsed)
            {
                // restoring the panel in the end to apply layout changes
                buttonOpenPanel1.Text = ">";
                splitContainer1.Panel1Collapsed = true;
            }
        }
        // Open the left panel
        else
        {
            if (splitContainer1.Panel1Collapsed)
            {
                // collapsing the panel in the end to apply layout changes
                buttonOpenPanel1.Text = "<";
                splitContainer1.Panel1Collapsed = false;
            }
        }

        splitContainer1.ResumeLayout();

        comboBoxSearchText.Focus();
    }

【讨论】:

    【解决方案3】:

    受 Lotus Notes 布局的启发,我设计了一些我认为在这种情况下有用的东西。它仅包含面板之间的一个按钮,用于切换单个面板的展开/折叠状态,但可以轻松修改为使用两个按钮来控制左右面板。它使用两个拆分容器,一个停靠在另一个内部,并使用“中间”面板的 mouseMove 事件来模拟拖动拆分器 (Moving a control by dragging it with the mouse in C#)。 此外,我使用容器的 ClientSizedChanged 事件来处理切换按钮图像的逻辑,而不是折叠/展开面板的方法 (Detect when SplitContainer collapsed changes)。

    设计:

    splitContainer1
    ╔════════════╤═════════════════════════════════╗
    ║            │ splitContainer2 (docked fill)   ║
    ║            │ ╔════════════╤════════════════╗ ║
    ║            │ ║            │                ║ ║
    ║            │ ║ Button(s)  │                ║ ║
    ║            │ ║ [<>]       │                ║ ║
    ║            │ ║            │                ║ ║
    ║            │ ╚════════════╧════════════════╝ ║
    ╚════════════╧═════════════════════════════════╝
    
    splitContainer2.Dock = DockStyle.Fill;
    splitContainer1 = splitContainer2.IsSplitterFixed = true;
    splitContainer2.Panel1.Cursor = Cursors.VSplit;
    

    向左或向右锚定按钮(或将多个按钮停靠在 tableLayout 控件内)。只需确保仍有部分面板可供单击/拖动即可。
    将中间面板的最大值设置为较低的数字。大小取决于您需要按钮的宽度。

    代码:

    面板将切换到相反状态
    如果您确实需要一个带有两个部分的按钮而不是两个按钮或一个切换按钮,则您需要单击鼠标坐标并根据单击发生的位置具有不同的逻辑。

    private void btnExpand_Click(object sender, EventArgs e)
    {
        splitContainer1.Panel1Collapsed = !splitContainer1.Panel1Collapsed;  
    }
    

    与展开/折叠相关的 Handel 逻辑。我选择使用这个事件是因为在我的程序中有几种方法可以让用户折叠/展开面板。

        private void splitContainer1_Panel2_ClientSizeChanged(object sender, EventArgs e)
        {
    
            if (splitContainer1.Panel1Collapsed)
            {
                splitContainer2.Panel1.Cursor = Cursors.Default;
                this.btnExpand.Image =  imageExpand;
            }
            Else
           {
                splitContainer2.Panel1.Cursor = Cursors.VSplit;
                this.btnExpand.Image = imageCollapse;
          }
        }
    

    处理由于移动人造分离器而调整面板的大小

        private void splitContainer2_Panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
    
        /* All you really need is this:
                    splitContainer1.SplitterDistance += e.X;  
    
        Note: Splitter distance must be a positive integer and e.X will be negitive when dragging to the left of the splitContainer. You could handel this check here or on the splitterMoving event.
    
            The code I have below shows how to “snap” a panel closed if the splitter is moved close enough to the edge 
        Or prevent a panel from being hidden from view (which could also be accomplished by setting the minimum size of a panel). 
    
        */
    
                if (e.X + splitContainer1.SplitterDistance < 40)
                {
    
                   while (splitContainer1.SplitterDistance > 1)
                        splitContainer1.SplitterDistance--;
                    splitContainer1.Panel1Collapsed = true;
    
                }
                else if ((e.X + splitContainer1.SplitterDistance) * 1.00 / this.Width * 1.00 < .75)
                    splitContainer1.SplitterDistance += e.X;  
                else
                    Cursor.Current = Cursors.No;
    
    
            }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-24
      • 1970-01-01
      • 2016-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多