オーバーライドされたペイントイベントで、他のコントロールにコントロールを描画したいと思います。描画とは、コントロールを他のコントロール内に配置するのではなく、実際の描画を意味します。それを行う良い方法はありますか?
5 に答える
ControlPaintクラスの静的メソッドを試してください。描画されたコントロールは、GUI の残りの部分のようにスキンされない場合がありますが、その効果はかなり信頼できます。以下は、私のコードの一部を簡略化したバージョンです。これは、 ControlPaint.DrawButtonメソッドを使用して、リスト項目をボタンのように見せるために、所有者描画 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メソッドを使用すると、これを非常に簡単に行うことができます。ボタンを作成し、同じサイズの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();
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);
おそらく、あなたが求めているのは、継承して独自の動作を作成できる「パネル」ですか?
class MyPanel : System.Windows.Forms.Panel
{
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
}
}
e.graphics を取得すると、コントロールの境界内で必要なことはほとんどすべて実行できます。メモリから、コントロールなどに最小サイズを設定できますが、詳細については、MSDN の windows.forms ドキュメントにジャンプする必要があります (または、ここで別の質問をすることができます;))。
または、たとえば機能を追加する場合は、コントロールから継承して、ペイント メソッドを強化およびオーバーライドする必要がありますか?
おそらく、これを何のためにしたいのか(質問で)詳しく説明できますか?