2012-06-30 26 views
7

Bir kontrolün arka planı olarak saydam bir kenarlığı olan bir görüntüyü görüntülemeye çalışıyorum. aşağıdaki gibiSaydam arka planla çizim kontrolü

Maalesef şeffaf alan ebeveyn şeklinde bir delik oluşturur: Yukarıdaki resimde

form ben benim kontrolüm arkasında görmek umduğu kırmızı arka plana sahip şeffaf alanlar. aşağıdaki gibi

kullandığım kodudur: I OnMouseMove ve OnMouseUp Olaylar uygulayan bir kontrol gerekli çünkü

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) 
    { 
     if (this.Image != null) 
     { 
      Graphics g = Graphics.FromImage(this.Image); 

      ImageAttributes attr = new ImageAttributes(); 

      //set the transparency based on the top left pixel 
      attr.SetColorKey((this.Image as Bitmap).GetPixel(0, 0), (this.Image as Bitmap).GetPixel(0, 0)); 

      //draw the image using the image attributes. 
      Rectangle dstRect = new Rectangle(0, 0, this.Image.Width, this.Image.Height); 

      e.Graphics.DrawImage(this.Image, dstRect, 0, 0, this.Image.Width, this.Image.Height, 
       GraphicsUnit.Pixel, attr); 
     } 
     else 
     { 
      base.OnPaint(e); 
     } 
    } 

    protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) 
    { 
     //base.OnPaintBackground(e); 
    } 

Bu sınıf bir PictureBox devralınır.

farklı fikirleri test başarılı olamadı günün en araştıran ama ne yazık ki en yalnızca tam çerçeve üzerinde çalışmak ve .Net değil CF. oldum

Herhangi bir fikir çok takdir edilecektir.

cevap

6

AH CF şeffaflık coşkusu. Ben bu konuda devam edebilir (ve in my blog ve Project Resistance code Ben yıllar önce yaptım).

özü budur. Çocuk kontrolünün alanlarını boyaması gerekir, ancak önce ebeveynine (sizin durumunuzdaki Form) geri dönmeli ve çocuğun kırpma bölgesinin dışında her yerde arka plan görüntüsünü yeniden çizmesini ve daha sonra kendini bunun üzerine çekmesini söylemelidir. . Bu biraz kafa karıştırıcı geliyorsa, çünkü öyle. Eğer Project Resistance bakarsak

Örneğin, (sadece bir Kontrol sahiptir) bir görüntüleme direnç ve bantları çizer. Bu bir resim arka plana sahip bir Form yatıyor ve o plan direncin saydam alanlar "yoluyla göstermek" gerekir: Bu işi yapan direncin çizim kodunda Yani

enter image description here

:

yeterince basit
protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    try 
    { 
     RECT rect = new RECT(this.Bounds); 

     // draw the blank 
     Infrastructure.GraphicTools.DrawTransparentBitmap(e.Graphics, m_blankImage, Bounds, 
       new Rectangle(0, 0, m_blankImage.Width, m_blankImage.Height)); 

     if (m_bandsImage != null) 
     { 
      // draw the bands 
      Infrastructure.GraphicTools.DrawTransparentBitmap(e.Graphics, m_bandsImage, Bounds, 
       new Rectangle(0, 0, m_bandsImage.Width, m_bandsImage.Height)); 
     } 
    } 
    finally 
    { 
    } 

    if (!Controller.TouchMode) 
    { 
     // TODO: draw in the selection arrow 
     // Controller.SelectedBand 
    } 
} 

. Anahtar Bu işi yapan baz OnPaint, var etmek o çağırır olmasıdır:

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) 
{ 
    // this assumes we're in a workspace, on MainForm (the whole Parent.Parent thing) 
    IBackgroundPaintProvider bgPaintProvider = Parent.Parent as IBackgroundPaintProvider; 
    if (bgPaintProvider != null) 
    { 
     Rectangle rcPaint = e.ClipRectangle; 
     // use the parent, since it's the workspace position in the Form we want, 
     // not our position in the workspace 
     rcPaint.Offset(Parent.Left, Parent.Top); 
     bgPaintProvider.PaintBackground(e.Graphics, e.ClipRectangle, rcPaint); 
    } 
} 

Bunu içeren Formu PaintBackground (bir kap denilen Kontrol aslında becuse bu durumda Parent.Parent var aradığını görebilirsiniz Çalışma alanı - davasında iki kez yürümeye gerek yok). Bu, şu anda gördüğünüz alanda arka plan görüntüsünü çiziyor "

public void PaintBackground(Graphics g, Rectangle targetRect, Rectangle sourceRect) 
{ 
    g.DrawImage(m_bmBuffer, targetRect, sourceRect, GraphicsUnit.Pixel); 
} 
+0

Vay, bunun için teşekkürler. Son derece yararlı ve detaylı bir açıklama. Bu konuda kesinlikle biraz zaman geçirdin. –

+0

@ctacke Size çok yakın bir Saydamlık çözümü ile geldim ve çalışma zamanında olduğu gibi tasarımcıda da çalışıyor. Kısa bir süre önce "Parent.Parent" olayı çalışmadığından, Kapsayıcı Denetimleri yerleştirirken çözümümün işe yaramayacağını anladım. Çalışma zamanında değil, tasarım zamanında çalışan this.TopLevelControl'e "Parent.Parent" anahtarını değiştirmeyi denedim. Konteynır kontrolleri içinde saydam kontrollerin yerleştirilmesi için bir çözüm bulabileceğiniz ve tasarımcının kontrolünüzü şeffaf hale getirdiği bir yer bulamadınız mı? –

+0

Yıllar önce kontrollerim için tasarımcı desteği almaya bile çalıştım. Benim için hiç bu kadar önemli olmamıştı ve her zaman kırılgantı.Bazen işe yaramazdı, başka zamanlar işe yaramazdı ve kendimi günlerce yanıcı bir şekilde üretiyordum, aslında hiçbir şey üretken bir şey yapmıyordum, bu yüzden hiç bir zaman bile tasarımcıyla uğraşmak zorunda kalmıyordum. – ctacke