我想在它被覆盖的绘制事件中在其他一些控件上绘制一个控件。通过绘图,我的意思是真正的绘图,而不是将控件放在另一个控件中。有什么好办法吗?
5 回答
尝试ControlPaint类的静态方法。绘制的控件可能不像 GUI 的其余部分那样被蒙皮,但效果会非常可信。下面是我的一些代码的精简版。它使用ControlPaint.DrawButton方法覆盖 ownerdrawn ListBox 的 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 方法,您可以很容易地做到这一点。这是一个片段,它将创建一个 Button 并将其绘制在相同大小的 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;
要在另一个控件的 Paint 事件中使用这种方法,您可以从上面的控件创建位图,然后将其绘制在控件的表面上,如下所示:
e.Graphics.DrawImage(bmp, 0, 0);
bmp.Dispose();
也许您所追求的是一个“面板”,您可以从中继承然后创建自己的行为?
class MyPanel : System.Windows.Forms.Panel
{
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
}
}
抓住 e.graphics,你可以在控制范围内做任何你想做的事情。从内存中,您可以在控件等上设置最小尺寸,但您需要跳转到 MSDN 中的 windows.forms 文档以获取更多详细信息(或者您可以在这里提出另一个问题;))。
或者,如果您例如添加功能,您应该从控件继承您尝试增强和覆盖它的绘制方法?
也许您可以详细说明(在您的问题中)您希望这样做是为了什么?
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 );
}
您可以按照@TcKs 的建议添加/覆盖 OnPaint 处理程序或使用 BitBlt 函数:
[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);