2009-06-17 85 views
0

我有兩個控件都包含在用戶控件中。獲取面板覆蓋的PictureBox區域

  • 面板位置:49,400
  • 面板尺寸:787,70
  • PictureBox的位置:25,0
  • PictureBox的尺寸:737,700

PictureBox的是在面板下方看到。

我可以使用一些建議來確定面板覆蓋的PictureBox圖像的區域,所以我可以在DrawImage調用中正確地將圖像複製到面板上。

我的答案是:我會從這個區域複製屏幕:24,400左上方,它將是714寬,70高 但是,如何自動化使用面板和圖片框的任意組合來實現可重用控件?

背景如果您需要更多信息:PictureBox包含地圖圖像。面板包含用於操作地圖的工具,面板位於PictureBox的頂部。面板需要是半透明的,所以地圖圖像仍然可以通過它看到。由於winforms繪製透明度的方式(通過控件樹調用父級繪製其自身) - 當我繪製面板時,它採用usercontrol背景的顏色,而不是它下面的地圖。

我對此的看法是:如果我可以將面板下方的地圖圖像複製到面板背景,然後繪製半透明背景,我將能夠模擬設計師請求的效果。

從面板的原始代碼是我從圖片框中抓取圖像的地方。

  Dim x As Integer = GetXOffset() 
      Dim y As Integer = GetYOffset() 

      Dim sizeOfImage As Size = New Size(ClientRectangle.Width _ 
            , ClientRectangle.Height) 
      bmpScreenshot = New Bitmap(sizeOfImage.Width, sizeOfImage.Height, _ 
        PixelFormat.Format32bppArgb) 

      gfxScreenshot = Graphics.FromImage(bmpScreenshot) 
      Dim destrect As New Rectangle(ClientRectangle.X, ClientRectangle.Y, _ 
         ClientRectangle.Width, ClientRectangle.Height) 


      gfxScreenshot.DrawImage(mPictureBox1.Image, destrect, New Rectangle(x, y, _ 
       sizeOfImage.Width, sizeOfImage.Height), GraphicsUnit.Pixel) 

我將此圖片複製到OnPaint事件中的背景。

If bmpScreenshot Is Nothing Then 
      PushScreen() 
     End If 
     If Not bmpScreenshot Is Nothing Then 
      pevent.Graphics.DrawImage(bmpScreenshot, GetPaintOffset()) 
     End If 

最後,從接受的答案中添加更改後,這裏是修改後的代碼,其中抓取圖像。

Dim sizeOfImage As Size = New Size(ClientRectangle.Width _ 
            , ClientRectangle.Height) 
      bmpScreenshot = New Bitmap(sizeOfImage.Width, sizeOfImage.Height, PixelFormat.Format32bppArgb) 

      gfxScreenshot = Graphics.FromImage(bmpScreenshot) 

      Dim rect As Rectangle = Rectangle.Intersect(mPictureBox1.Bounds, Bounds) 
      Dim destrect As Rectangle = New Rectangle(rect.Left - Left, _ 
      rect.Top - Top, rect.Width, rect.Height) 
      Dim imgrect As Rectangle = _ 
       New Rectangle(rect.Left - mPictureBox1.Bounds.Left, _ 
       rect.Top - mPictureBox1.Bounds.Top, rect.Width, rect.Height) 

      gfxScreenshot.DrawImage(mPictureBox1.Image, destrect, _ 
       imgrect, GraphicsUnit.Pixel) 

回答

3

您可以使用Rectangle.Intersect方法(連同一點點計算)來獲得您想要的結果。 C#示例:

Rectangle rect = Rectangle.Intersect(_pictureBox.Bounds, _panel.Bounds); 
rect = new Rectangle(rect.Top - _panel.Top, rect.Left - _panel.Left, rect.Width, rect.Height); 
e.Graphics.FillRectangle(Brushes.Red, rect); 

更新

我這個多一點發揮各地,並與下面的解決方案來了,我覺得有點簡單,也有點更強大的(此時VB。 NET代碼):

Private Sub DrawPanelBackground(ByVal pictureBox As PictureBox, ByVal panel As Panel) 
    If pictureBox.Image Is Nothing Then 
     Exit Sub 
    End If 

    Dim rect As Rectangle = New Rectangle(pictureBox.Left - panel.Left, pictureBox.Top - panel.Top, pictureBox.Image.Width, pictureBox.Image.Height) 
    Using g As Graphics = Panel.CreateGraphics() 
     g.DrawImage(pictureBox.Image, rect) 
    End Using 
End Sub 
+0

如果Panel和PictureBox共享一個父級(大概是用戶控件),Control.Bounds方法將提供所需的內容。 – 2009-06-17 19:55:17