受 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;
}
}