C# WinForms 中的自定义绘制拆分器控件
Custom paint Splitter control in 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);
}
}
这只会绘制控件的背景,但不会在拖动时绘制拆分器。
有什么想法吗?
旧的 Splitter 控件使用私有绘制方法来产生棋盘效果,因此您无法覆盖任何东西来替换它。
您可以通过在屏幕上看到的棋盘控件的 space 中拖动您自己的控件来伪造它。这可能会产生一些闪烁:
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(e.X - (e.X - 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 控件。
LarsTech 提供的 post 答案非常好,但处理程序闪烁有点烦人。如果您将 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。在另一个 post 中,我使用原始拆分器的源代码创建了一个新的拆分器控件,但更改了突出显示的渲染:
我正在尝试绘制当您拖动拆分器控件时出现的拆分线:
从这张图片可以看出,默认的分割线是棋盘格。
...这行不通:
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);
}
}
这只会绘制控件的背景,但不会在拖动时绘制拆分器。
有什么想法吗?
旧的 Splitter 控件使用私有绘制方法来产生棋盘效果,因此您无法覆盖任何东西来替换它。
您可以通过在屏幕上看到的棋盘控件的 space 中拖动您自己的控件来伪造它。这可能会产生一些闪烁:
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(e.X - (e.X - 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 控件。
LarsTech 提供的 post 答案非常好,但处理程序闪烁有点烦人。如果您将 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。在另一个 post 中,我使用原始拆分器的源代码创建了一个新的拆分器控件,但更改了突出显示的渲染: