有没有办法在C#中的其他控件上绘制控件?

有没有办法在C#中的其他控件上绘制控件?,c#,gdi+,C#,Gdi+,我想在它的重写绘制事件中在其他控件上绘制一个控件。我所说的绘图是指真实的绘图,而不是将控件放在另一个控件中。有什么好办法吗?也许你想要的是一个“面板”,你可以从中继承,然后创建自己的行为 class MyPanel : System.Windows.Forms.Panel { protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { base.OnPaint(e); }

我想在它的重写绘制事件中在其他控件上绘制一个控件。我所说的绘图是指真实的绘图,而不是将控件放在另一个控件中。有什么好办法吗?

也许你想要的是一个“面板”,你可以从中继承,然后创建自己的行为

class MyPanel : System.Windows.Forms.Panel
{
    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
        base.OnPaint(e);
    }
}
抓取e.graphics,你可以在控件的范围内做任何你想做的事情。从内存中,您可以设置控件的最小大小等,但您需要跳转到MSDN中的windows.forms文档以了解更多详细信息(或者您可以在此处询问另一个问题;)

或者,如果您的实例正在添加功能,您应该从控件继承您试图增强和覆盖它的绘制方法吗


也许您可以详细说明(在您的问题中)您希望这样做的原因?

您可以按照@TcKs的建议添加/覆盖OnPaint处理程序,或者使用BitBlt函数:

public delegate void OnPaintDelegate( PaintEventArgs e );
private void panel1_Paint( object sender, PaintEventArgs e ) {
    OnPaintDelegate paintDelegate = (OnPaintDelegate)Delegate.CreateDelegate(
        typeof( OnPaintDelegate )
        , this.button1
        , "OnPaint" );
    paintDelegate( e );
}
[DllImport("gdi32.dll")]
private static extern bool BitBlt(
    IntPtr hdcDest,
    int nXDest, 
    int nYDest, 
    int nWidth, 
    int nHeight, 
    IntPtr hdcSrc, 
    int nXSrc, 
    int nYSrc, 
    int dwRop 
);

private const Int32 SRCCOPY = 0xCC0020;

....

Graphics sourceGraphics = sourceControl.CreateGraphics();
Graphics targetGraphics = targetControl.CreateGraphics();
Size controlSize = sourceControl.Size;
IntPtr sourceDc = sourceGraphics.GetHdc();
IntPtr targerDc = targetGraphics.GetHdc();
BitBlt(targerDc, 0, 0, controlSize.Width, controlSize.Height, sourceDc, 0, 0, SRCCOPY);
sourceGraphics.ReleaseHdc(sourceDc);
targetGraphics.ReleaseHdc(targerDc);

ControlPaint类上尝试静态方法。绘制的控件可能不像GUI的其他部分那样被蒙皮,但是效果会非常可信。下面是我的一些代码的精简版本。它使用ControlPaint.DrawButton方法覆盖ownerdrawn列表框的DrawItem方法,使列表项看起来像按钮

在这个类中,复选框,组合,甚至拖动手柄都有很多优点

protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)
{
    e.DrawBackground();

    if (e.Index > -1)
    {
        String itemText = String.Format("{0}", this.Items.Count > 0 ? this.Items[e.Index] : this.Name);

        //Snip

        System.Windows.Forms.ControlPaint.DrawButton(e.Graphics, e.Bounds, ButtonState.Normal);

        e.Graphics.DrawString(itemText, this.Font, SystemBrushes.ControlText, e.Bounds);
    }
}

通过使用控件的DrawToBitmap方法,可以非常轻松地完成此操作。下面是一个片段,它将创建一个按钮并将其绘制在相同大小的PictureBox上:

Button btn = new Button();
btn.Text = "Hey!";
Bitmap bmp = new Bitmap(btn.Width, btn.Height);
btn.DrawToBitmap(bmp, new Rectangle(0, 0, btn.Width, btn.Height));
PictureBox pb = new PictureBox();
pb.Size = btn.Size;
pb.Image = bmp;
要在另一个控件的绘制事件中使用此方法,您可以如上所述从控件创建位图,然后在控件的曲面上绘制位图,如下所示:

e.Graphics.DrawImage(bmp, 0, 0);
bmp.Dispose();

你能解释一下原因吗?这个用例可能有助于给出更好的答案。另外,您使用的是winforms还是WPF?我认为“gdi+”标记指向winforms