简体   繁体   English

C#WinForms中的自定义绘画拆分器控件

[英]Custom paint Splitter control in C# WinForms

I am trying to paint the split line that appears when you drag a splitter control: 我试图绘制拖动分隔器控件时出现的分隔线:

分离器

As you can see from this image, the default splitter is a checkerboard. 从该图像可以看到,默认的拆分器是棋盘格。

...this doesn't work: ...这不起作用:

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

this just paints the background of the control but not the splitter when it's dragged. 这只是绘制控件的背景,而不是拖动时的拆分器。

Any ideas? 有任何想法吗?

The answer posted by LarsTech is really good, But the handler flickers are somehow annoying. LarsTech发布的答案确实很好,但是处理程序的闪烁某种程度上令人讨厌。 Instead of showing the control in Form , if you show a Form as splitter handler and show it above the Container of splitter, the flickers will be gone. 而不是显示在控制的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();
}

Here is the form which I used as highlight: 这是我用来突出显示的形式:

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

To see a custom splitter which supports transparent handler take a look at this related post. 要查看支持透明处理程序的自定义拆分器,请查看此相关文章。 In the other post I created a new splitter control using source codes of original splitter, but changed rendering the highlight: 在另一篇文章中,我使用原始拆分器的源代码创建了一个新的拆分器控件,但是更改了突出显示:

The old Splitter control uses a private painting method to produce that checkerboard effect, so there isn't any thing you can override to replace that. 旧的Splitter控件使用私有的绘画方法来产生棋盘格效果,因此您无法重写任何东西来替换它。

You can fake it by dragging your own control in the space of the checkerboard control you see on the screen. 您可以通过在屏幕上看到的棋盘格控件的空间中拖动自己的控件来伪造它。 This may produce some flicker: 这可能会产生闪烁:

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();
}

The Splitter control was deprecated in favor of the SplitContainer control. 不推荐使用Splitter控件,而推荐使用SplitContainer控件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM