使拆分器对拆分面板可见

时间:2010-03-06 12:52:27

标签: c# .net winforms

如何让分割面板拆分器对用户可见,而不是只在鼠标悬停时光标变化不可见?

12 个答案:

答案 0 :(得分:51)

出现这个问题是因为SplitContainer控件有没有直接属性来设置可拖动分割条本身的样式。

有几种方法可以实现这一点,即使这里发布的其他答案有效,我在下面与您分享的最终方式也是快速,可靠和最简单的方法。

@BluMonkMN提出了一种使用3D边框的方法,但是如果你不想要任何边框怎么办?

@Giles Bathgate建议添加一个Paint事件处理程序,即使它确实很优雅并且确实有效,但需要稍微降低性能,要求您为在C#级别执行的项目添加更多代码,并且有一天可能成为维修问题。

@Philip Fourie建议更改SplitContainer.BackColor属性值;然而,最初导致控件的整个背景改变颜色,而不仅仅是分割条,导致没有颜色对比。

所以,我的解决方案是@Philip Fourie的增强功能。

首先,我提到SplitContainer实际上有两个不同的子容器,两者都由分割条分隔。这两个属性由Panel1Panel2属性表示。除了其他几个属性之外,它们中的每一个本质上都是一个具有自己的BackColor属性的Panel容器。

SplitContainer拥有自己的BackColor属性,总共有三种独特的可能颜色。

现在,如果您要设置此SplitContainer.BackColor属性,Panel1Panel2"子控件"会自动继承那个颜色值,现在它们都是一样的,没有引起视觉对比! 只有在Panel1.BackColor和/或Panel2.BackColor属性尚未由您明确设置时(即使查看其属性值),才会发生此[可能不合需要的]属性值继承提前的Visual Studio Properties窗口将显示" Control。")

因此,您设置属性的顺序非常重要:

  1. 同时设置" child" Panel1.BackColorPanel2.BackColor属性为以外的其他内容默认值" Control"强制一个明确的价值(即使你真的想要"控制&#34 ;;我们稍后会修复它。)
  2. 设置" parent" SplitContainer.BackColor为您希望分割条的颜色。{/ li>
  3. 最后,返回并将Panel1.BackColorPanel2.BackColor属性设置为您希望它们的颜色(可能返回" Control&#34 ;.)
  4. 正如@Philip Fourie回答的那样,您可能希望设置Width属性,实际上始终命名为SplitterWidth,而不管[Horizo​​ntal vs. Vertical] Orientation属性。

    以下是一些有用的提示:

    在Visual Studio表单设计器中工作时,如果单击拆分器栏两侧的SplitContainer,则会选择那个 Panel1Panel2"孩子"子容器。但是如果你点击分割条本身,你就会选择"父母" SplitContainer

    与@Stuart Helwig建议的相关,默认SplitterWidth将导致分割条在焦点处被勾勒出轮廓,从而遮挡您选择的颜色。将值提高到56或更高,这也使最终用户更容易抓住&阻力。

    成品。快乐的编码!

答案 1 :(得分:35)

尝试将BorderStyle设置为Fixed3D

答案 2 :(得分:17)

您可以通过将以下事件处理程序添加到splitcontainer paint事件来绘制自己的拆分器栏。

private void SplitterPaint(object sender, PaintEventArgs e)
{
    SplitContainer s = sender as SplitContainer;
    if (s != null) {
        int top = 5;
        int bottom = s.Height - 5;
        int left = s.SplitterDistance;
        int right = left + s.SplitterWidth - 1;
        e.Graphics.DrawLine(Pens.Silver, left, top, left, bottom);
        e.Graphics.DrawLine(Pens.Silver, right, top, right, bottom);
    }
}

答案 3 :(得分:2)

一种方法是更改​​拆分器的BackColorWidth/Height属性(取决于拆分器的方向)

答案 4 :(得分:2)

您可以在设计器中使用SplitterColor来更改分割器边框颜色。

public class SplitContainerCustomSplitter : SplitContainer
{
    [DefaultValue(typeof(Color), "Black")]
    public Color SplitterColor { get; set; } = Color.Black;

    protected override void OnPaint(PaintEventArgs pevent)
    {
        Graphics g = pevent.Graphics;
        Rectangle rect = SplitterRectangle;

        using (Pen pen = new Pen(SplitterColor))
        {
            if (Orientation == Orientation.Vertical)
            {
                g.DrawLine(pen, rect.Left, rect.Top, rect.Left, rect.Bottom - 1);
                g.DrawLine(pen, rect.Right - 1, rect.Top, rect.Right - 1, rect.Bottom - 1);
            }
            else
            {
                g.DrawLine(pen, rect.Left, rect.Top, rect.Right - 1, rect.Top);
                g.DrawLine(pen, rect.Left, rect.Bottom - 1, rect.Right, rect.Bottom - 1);
            }
        }
    }
}

答案 5 :(得分:1)

除了将其BorderStyle Fixed3D设为@BlueMonkMN建议我经常发现splitContainer对象上的默认SplitterWidth值为4,有点窄。

如果您使用3D边框将其提升至约6,则对用户来说更为明显。

答案 6 :(得分:0)

改进了Giles Bathgate的答案:

private void ds_SplitContainer_Paint(object sender, PaintEventArgs e)
{
    SplitContainer l_SplitContainer = sender as SplitContainer;

    if (l_SplitContainer != null)
    {
        Rectangle ll_ShrinkedSplitterRectangle = l_SplitContainer.SplitterRectangle;
        ll_ShrinkedSplitterRectangle.Offset(0, 2);
        ll_ShrinkedSplitterRectangle.Height = ll_ShrinkedSplitterRectangle.Height - 2;
        e.Graphics.FillRectangle(Brushes.Silver, ll_ShrinkedSplitterRectangle);
    }
}

答案 7 :(得分:0)

这是一个水平分割器的快速实现,它充满了一种颜色,有一个顶部和底部边框(类似于Visual Studio分割器),中间有一个抓点。

    private void splitContainer_Paint(object sender, PaintEventArgs e)
    {
        SplitContainer s = sender as SplitContainer;
        if (s != null)
        {
            int gripLineWidth = 9;
            // Fill Splitter rectangle
            e.Graphics.FillRectangle(SystemBrushes.ControlDark, 
                s.SplitterRectangle.X, s.SplitterDistance, s.SplitterRectangle.Width, s.SplitterWidth);
            // Draw Single Line Border on Top and Bottom
            e.Graphics.DrawLine(Pens.LightSlateGray,
                s.SplitterRectangle.X, s.SplitterDistance, s.SplitterRectangle.Width, s.SplitterDistance);
            e.Graphics.DrawLine(Pens.LightSlateGray,
                s.SplitterRectangle.X, s.SplitterDistance + s.SplitterWidth - 1, s.SplitterRectangle.Width, s.SplitterDistance + s.SplitterWidth - 1);
            // Draw gripper dots in center
            e.Graphics.DrawLine(_dashedPen,
                ((s.SplitterRectangle.Width / 2) - (gripLineWidth / 2)),
                s.SplitterDistance + s.SplitterWidth / 2,
                ((s.SplitterRectangle.Width / 2) + (gripLineWidth / 2)),
                s.SplitterDistance + s.SplitterWidth / 2);
        }
    }

您可以在执行绘图的类中创建一个Pen作为成员变量,该绘图将在您的类似内容中绘制虚线:

private static Pen _dashedPen = new Pen(Color.DarkRed, 1);
_dashedPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;

答案 8 :(得分:0)

BackColor的{​​{1}}属性设置为其他颜色。让我们说黑色。然后每个SplitContainer,将其SpliterPanel属性更改为不同的颜色。让我们说白。然后您会注意到SplitLine将变得更加明显。 :)

答案 9 :(得分:0)

在尝试了一些这里建议的方法而不是逗我之后,我决定在panel1和panel2中放入一个薄标签,与分离器对齐,一切正常。

(label's.Autosize=false, label's.Text = "", label's.Color=SystemColor.Selected,  label1.Dock=left; label2.Dock=right)

答案 10 :(得分:0)

这是对GlobalSoftwareSociety's great answer的改进。

为防止面板继承BackColor,只需要写入属性一次。事实上,您可以简单地将属性分配给自己。这也适用于其他类型的控件和类似继承的属性,如字体。

另外,为了避免烦人的选择矩形,请使SplitContainer不是一个tabstop,并在鼠标上启动第一个面板。

(需要小心;首先我尝试在Enter事件中调用“tab to next control”调用,但这阻止了所有子控件的激活。)

总之,这使修复看起来像:

splitBox.Panel1.BackColor = splitBox.Panel1.BackColor;
splitBox.Panel2.BackColor = splitBox.Panel2.BackColor;
splitBox.BackColor = yourFavouriteColor;
splitBox.SplitterWidth = yourFavouriteSize;
splitBox.TabStop = false;
splitBox.MouseUp += (s, e) => splitBox.ActiveControl = splitBox.Panel1;

答案 11 :(得分:-1)

实际上可以看到分割线。真正的问题是很难与其他控件区别开来。

一个想法是为拆分容器设置一个新的背景颜色,并使其与子面板不同。

有时我们可以从设计师的角度解决问题,而不是开发人员。 : - )