C#WinForms中的自定义绘制分割器控件

我正在尝试绘制拖动分割器控件时出现的分割线:

分离器

从该图像中可以看出,默认分割器是棋盘格。

……这不起作用:

public partial class MockForm : Form { public MockForm() { InitializeComponent(); this.splitter1.Paint += splitter1_Paint; } private void splitter1_Paint(object sender, PaintEventArgs e) { e.Graphics.Clear(Color.Red); } } 

这只是绘制控件的背景,而不是拖动时的分割器。

有任何想法吗?

LarsTech发布的答案非常好,但处理程序闪烁的方式令人讨厌。 如果您将Form显示为拆分处理程序并将其显示在分隔符容器上方,则闪烁将消失,而不是在Form中显示控件。

 HighLight f = new HighLight() { BackColor = Color.Red }; private void splitter1_SplitterMoving(object sender, SplitterEventArgs e) { this.splitter1.Parent.Refresh(); f.Location = this.splitter1.Parent.PointToScreen(new Point(e.SplitX, e.SplitY)); f.Size = this.splitter1.Size; if (!f.Visible) f.ShowInactiveTopmost(); } private void splitter1_SplitterMoved(object sender, SplitterEventArgs e) { f.Hide(); } 

这是我用作突出显示的表单:

 using System; using System.Runtime.InteropServices; using System.Windows.Forms; public class HighLight : Form { public HighLight() { Opacity = 0; FormBorderStyle = FormBorderStyle.None; ShowInTaskbar = false; StartPosition = FormStartPosition.Manual; } protected override void OnDeactivate(EventArgs e) { base.OnDeactivate(e); this.Hide(); } private const int SW_SHOWNOACTIVATE = 4; private const int HWND_TOPMOST = -1; private const uint SWP_NOACTIVATE = 0x0010; [DllImport("user32.dll", EntryPoint = "SetWindowPos")] static extern bool SetWindowPos(int hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); public void ShowInactiveTopmost() { ShowWindow(this.Handle, SW_SHOWNOACTIVATE); SetWindowPos(this.Handle.ToInt32(), HWND_TOPMOST, this.Left, this.Top, this.Width, this.Height, SWP_NOACTIVATE); this.Opacity = 1; } } 

要查看支持透明处理程序的自定义拆分器,请查看此相关post。 在另一篇文章中,我使用原始拆分器的源代码创建了一个新的拆分器控件,但更改了渲染突出显示:

  • 更改拆分器突出显示/调整线条大小

旧的Splitter控件使用私有绘制方法来产生棋盘效果,因此没有任何东西可以覆盖来替换它。

您可以通过在屏幕上看到的棋盘控件的空间中拖动您自己的控件来伪造它。 这可能会产生一些闪烁:

 Control draggingControl = new Control { BackColor = Color.Green, Visible = false }; public MockForm() { InitializeComponent(); this.Controls.Add(draggingControl); splitter1.SplitterMoving += splitter1_SplitterMoving; splitter1.SplitterMoved += splitter1_SplitterMoved; } void splitter1_SplitterMoving(object sender, SplitterEventArgs e) { draggingControl.Bounds = new Rectangle(new Point(eX - (eX - e.SplitX), 0), splitter1.Size); if (!draggingControl.Visible) { draggingControl.Visible = true; draggingControl.BringToFront(); } this.Refresh(); } void splitter1_SplitterMoved(object sender, SplitterEventArgs e) { draggingControl.Visible = false; this.Refresh(); } 

不推荐使用Splitter控件,而使用SplitContainer控件。