SplitContainer的分割条中曾经有3个点。就像StackOverflow上有三行问题详细信息文本框一样,可以抓取它。如何使用.NET中的SplitContainer的分割条执行此操作?
答案 0 :(得分:43)
并不是说我有什么可以反对Alex的答案,但我认为我会分享这个解决方案,因为它看起来对我来说有点好(无论如何在XP机器上?)。
private void SplitContainer_Paint(object sender, PaintEventArgs e)
{
var control = sender as SplitContainer;
//paint the three dots'
Point[] points = new Point[3];
var w = control.Width;
var h = control.Height;
var d = control.SplitterDistance;
var sW = control.SplitterWidth;
//calculate the position of the points'
if (control.Orientation == Orientation.Horizontal)
{
points[0] = new Point((w / 2), d + (sW / 2));
points[1] = new Point(points[0].X - 10, points[0].Y);
points[2] = new Point(points[0].X + 10, points[0].Y);
}
else
{
points[0] = new Point(d + (sW / 2), (h / 2));
points[1] = new Point(points[0].X, points[0].Y - 10);
points[2] = new Point(points[0].X, points[0].Y + 10);
}
foreach (Point p in points)
{
p.Offset(-2, -2);
e.Graphics.FillEllipse(SystemBrushes.ControlDark,
new Rectangle(p, new Size(3, 3)));
p.Offset(1, 1);
e.Graphics.FillEllipse(SystemBrushes.ControlLight,
new Rectangle(p, new Size(3, 3)));
}
}
希望这能让某些人高兴吗? HAA!
答案 1 :(得分:12)
没有实施。如果您喜欢该功能,最好派生SplitContainer并覆盖OnPaint方法。
更新1
这里有一些代码可以满足您的要求。它是在VB.NET中,点放置可以做一些调整。总的来说,代码按预期工作。
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Drawing
Public Class SplitContainerEx
Inherits SplitContainer
''' <summary>Determines the thickness of the splitter.</summary>
<DefaultValue(GetType(Integer), "5"), Description("Determines the thickness of the splitter.")> _
Public Overridable Shadows Property SplitterWidth() As Integer
Get
Return MyBase.SplitterWidth
End Get
Set(ByVal value As Integer)
If value < 5 Then value = 5
MyBase.SplitterWidth = value
End Set
End Property
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
'paint the three dots
Dim points(2) As Point
Dim pointRect = Rectangle.Empty
'calculate the position of the points
If Orientation = Windows.Forms.Orientation.Horizontal Then
points(0) = New Point((MyBase.Width \ 2), SplitterDistance + (SplitterWidth \ 2))
points(1) = New Point(points(0).X - 10, points(0).Y)
points(2) = New Point(points(2).X + 10, points(0).Y)
pointRect = New Rectangle(points(1).X - 2, points(1).Y - 2, 25, 5)
Else
points(0) = New Point(SplitterDistance + (SplitterWidth \ 2), (MyBase.Height \ 2))
points(1) = New Point(points(0).X, points(0).Y - 10)
points(2) = New Point(points(0).X, points(0).Y + 10)
pointRect = New Rectangle(points(1).X - 2, points(1).Y - 2, 5, 25)
End If
e.Graphics.FillRectangle(Brushes.Gray, pointRect)
For Each p In points
p.Offset(-1, -1)
e.Graphics.FillEllipse(Brushes.Black, New Rectangle(p, New Size(3, 3)))
Next
End Sub
End Class
更新2
我提出了C#等价物,因为你标记了你的问题
如果vb makes you sick
,请学习转到Convert VB.NET to C# - Developer Fusion并进行VB转换为C#。
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
public class SplitContainerEx : SplitContainer
{
/// <summary>Determines the thickness of the splitter.</summary>
[DefaultValue(typeof(int), "5"), Description("Determines the thickness of the splitter.")]
public virtual new int SplitterWidth {
get { return base.SplitterWidth; }
set {
if (value < 5)
value = 5;
base.SplitterWidth = value;
}
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
//paint the three dots
Point[] points = new Point[3];
Rectangle pointRect = Rectangle.Empty;
//calculate the position of the points
if (Orientation == System.Windows.Forms.Orientation.Horizontal) {
points[0] = new Point((int)(base.Width / 2), SplitterDistance + (int)(SplitterWidth / 2));
points[1] = new Point(points[0].X - 10, points[0].Y);
points[2] = new Point(points[2].X + 10, points[0].Y);
pointRect = new Rectangle(points[1].X - 2, points[1].Y - 2, 25, 5);
} else {
points[0] = new Point(SplitterDistance + (int)(SplitterWidth / 2), (int)(base.Height / 2));
points[1] = new Point(points[0].X, points[0].Y - 10);
points[2] = new Point(points[0].X, points[0].Y + 10);
pointRect = new Rectangle(points[1].X - 2, points[1].Y - 2, 5, 25);
}
e.Graphics.FillRectangle(Brushes.Gray, pointRect);
foreach (Point p in points) {
p.Offset(-1, -1);
e.Graphics.FillEllipse(Brushes.Black, new Rectangle(p, new Size(3, 3)));
}
}
}
答案 2 :(得分:6)
您最接近而不自己绘画就是将BorderStyle
更改为Fixed3D
。这将在两个小组之间给你一种“条形”。
如果您不喜欢两个面板本身的凹陷外观,可以通过将分割面板放在另一个面板中并将其Location
设置为负值(例如,“隐藏”外边框) -n,-n
)及其父级面板尺寸+ 2*n
的尺寸。然后我将Anchor设置为Top | Left | Bottom | Right
,以便在调整父面板大小时保持这种状态。
这是一种kludge,但我当然认为这样做,因为我讨厌没有迹象表明“抓点”在哪里。
答案 3 :(得分:2)
我更喜欢的是添加一个油漆处理程序。这意味着您不需要派生新类,并且如果将静态函数放入可以由各种项目共享的文件中,则静态函数可以轻松重用 - 只需记住使用“添加为链接”,以便在编辑时文件,它将被包含它的所有项目更改。这方面的主要缺点是它不会自动处理更改控件的颜色。
...
mySplitContainer.Paint += CustomPaint.PaintSplitterWithHandle;
...
public static class CustomPaint {
public static void PaintSplitterWithHandle(object sender, PaintEventArgs p) {
SplitContainer splitter = sender as SplitContainer;
if (splitter == null) return;
if (splitter.Orientation == Orientation.Horizontal)
p.Graphics.DrawLine(Pens.DarkGray,
0, splitter.SplitterDistance + (splitter.SplitterWidth / 2),
splitter.Width, splitter.SplitterDistance + (splitter.SplitterWidth / 2));
else
p.Graphics.DrawLine(Pens.DarkGray,
splitter.SplitterDistance + (splitter.SplitterWidth / 2), 0,
splitter.SplitterDistance + (splitter.SplitterWidth / 2), splitter.Height);
}
}
答案 4 :(得分:2)
我并不是真的想做一个抓握手柄的笨拙工作,因为我正在编写一个内部管理工具,这太过分了。根据{{3}},您可以对SplitContainer进行子类化,覆盖OnPaint(PaintEventArgs)方法并包含以下行:
ControlPaint.DrawGrabHandle(e.Graphics, SplitterRectangle, true, Enabled);
这将绘制窗格之间的基本分界线。