2012-09-25 56 views
3

我修改了在CodeProject上找到的SuperContextMenuStrip以滿足我的一些項目需求。我將它用作GMap.NET Map Control上地圖標記的工具提示。這裏是什麼樣子的樣本:創建一個控件的透明部分來查看它下面的控件

enter image description here

我想這樣做是很這了一點使它看起來更像是一個泡沫。類似於舊的谷歌地圖stytle提示:

enter image description here

我花了一些時間在控制透明度搜索和我知道這不是一件容易的事情。 This SO question in particular illustrates that.

我已經考慮重寫SuperContextMenuStripOnPaint方法來繪製GMap.NET控件是SuperContextMenuStrip下的背景,但即使這樣做法將在標誌懸掛在GMap.NET控制的情況下失敗:

enter image description here

什麼是創造的透明度,我尋找的類型的正確方法是什麼?

+0

這樣的回答可以幫助你 - 我不確定...... HTTP://social.msdn。 microsoft.com/Forums/en-US/winforms/thread/c71b3076-dca6-48ac-9b19-45f58346b9b1?persist=True – MoonKnight

+0

改爲使其成爲窗體,使用Show(所有者)超載顯示它。使用其TransparencyKey和Opacity鍵獲得效果。 –

回答

3

在Windows窗體中,通過定義區域來實現透明度(或繪製不規則形狀的窗口)。引用MSDN

窗口區域是窗口內像素的集合,其中操作系統允許繪製 。

在你的情況,你應該有一個位圖,你將用作掩碼。位圖應該至少有兩種不同的顏色。其中一種顏色應代表您希望透明的控制部分。

然後,您可以創建一個區域是這樣的:

// this code assumes that the pixel 0, 0 (the pixel at the top, left corner) 
// of the bitmap passed contains the color you wish to make transparent. 

     private static Region CreateRegion(Bitmap maskImage) { 
      Color mask = maskImage.GetPixel(0, 0); 
      GraphicsPath grapicsPath = new GraphicsPath(); 
      for (int x = 0; x < maskImage.Width; x++) { 
       for (int y = 0; y < maskImage.Height; y++) { 
        if (!maskImage.GetPixel(x, y).Equals(mask)) { 
          grapicsPath.AddRectangle(new Rectangle(x, y, 1, 1)); 
         } 
        } 
      } 

      return new Region(grapicsPath); 
     } 

你可以這樣設置控制的地區由CreateRegion方法返回的地區。

this.Region = CreateRegion(YourMaskBitmap); 

刪除透明度:

this.Region = new Region(); 

正如你可能從上面的代碼告訴,打造區域是昂貴的資源,明智的。如果您需要多次使用它們,我建議將區域保存在變量中。如果以這種方式使用緩存區域,很快就會遇到另一個問題。該分配將第一次工作,但在隨後的調用中您將得到一個ObjectDisposedException。

一個小調查與refrector將在區域屬性的set訪問中透露下面的代碼:

  this.Properties.SetObject(PropRegion, value); 
      if (region != null) 
      { 
       region.Dispose(); 
      } 

域對象是使用後丟棄! 幸運的是,該區域是可克隆和所有你需要做的,保護你的域對象是指定一個克隆:

private Region _myRegion = null; 
private void SomeMethod() { 
    _myRegion = CreateRegion(YourMaskBitmap);    
} 

private void SomeOtherMethod() { 
    this.Region = _myRegion.Clone(); 
} 
+0

你是男人!我從來沒有玩過Control的'Region'屬性。在我所有的在線搜索這個問題的答案,它從來沒有出現。它完美的作品。然而,在我的情況下,我沒有使用「Bitmap」來生成'GraphicsPath.',而是直接繪製'GraphicsPath'。礦井很簡單 - 它是一個圓角矩形,左下角有一點點。我用這個代碼繪製圓角矩形。 http://www.switchonthecode.com/tutorials/csharp-creating-rounded-rectangles-using-a-graphics-path再次感謝! –

+0

@ michael.mankus歡迎您 – Ben