2010-06-14 172 views
0

我嘗試編寫一個將自己繪製在控件上的類(.NET )。但是這個「東西」不能正確地重繪自己(不會使其父母無效)。在.NET中繪製矩形

這裏的用法:

Public Class Form1 
    Dim myCadre As New Cadre 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    For i As Integer = 0 To 100 
     myCadre.Location = New Point(myCadre.Location.X + 1, myCadre.Location.Y + 1) 
     System.Threading.Thread.Sleep(500) 
    Next i 
    End Sub 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    myCadre.Location = New Point(10, 10) 
    myCadre.Size = New Size(60, 90) 
    myCadre.Parent = Me 
    End Sub 
End Class 

下面是代碼:

Public Class Cadre 
    Private _Rectangle As Rectangle 
    Private _Parent As Control 
    Public Event ParentChanged As EventHandler 
    Private _Location As Point 

    Public ReadOnly Property DisplayRectangle() As Rectangle 
    Get 
     Return _Rectangle 
    End Get 
    End Property 

    Public Property Location() As Point 
    Get 
     Return _Rectangle.Location 
    End Get 
    Set(ByVal value As Point) 
     _Rectangle.Location = value 
     DrawInternal() 
    End Set 
    End Property 

    Public Property Size() As Size 
    Get 
     Return _Rectangle.Size 
    End Get 
    Set(ByVal value As Size) 
     _Rectangle.Size = value 
     DrawInternal() 
    End Set 
    End Property 

    Public Property Parent() As Control 
    Get 
     Return _Parent 
    End Get 
    Set(ByVal value As Control) 
     If _Parent IsNot value Then 
     _Parent = value 
     OnParentChanged(Me, EventArgs.Empty) 
     End If 
    End Set 
    End Property 

    Overridable Sub OnParentChanged(ByVal sender As Object, ByVal e As EventArgs) 
    DrawInternal() 
    RaiseEvent ParentChanged(sender, e) 
    End Sub 

    Private Sub DrawInternal() 
    If _Parent Is Nothing Then Return 
    Dim g As Graphics = _Parent.CreateGraphics() 

    g.DrawRectangle(Pens.Black, Me._Rectangle) 
    End Sub 
End Class 
  • 我做錯了嗎?
  • 更好的是:使用private Graphic g和 設置它,只有當父母換一次, 或創建gDrawInternal
  • 是否有可能有Click事件?

幹部V2(後溫貝託建議):

Public Class Cadre 
    Private _FormerRectangle As Rectangle 
    Private _Rectangle As Rectangle 
    Private WithEvents _Parent As Control 
    Public Event ParentChanged As EventHandler 
    Private _Location As Point 

    Public Sub New() 
    _FormerRectangle = New Rectangle 
    _Rectangle = _FormerRectangle 
    End Sub 

    Private Sub DrawInternal(ByVal sender As Object, ByVal e As PaintEventArgs) Handles _Parent.Paint 
    If _FormerRectangle <> _Rectangle Then 
     _Parent.Invalidate(_FormerRectangle, False) ' !!! does not work ' 
    End If 

    e.Graphics.DrawRectangle(Pens.Black, Me._Rectangle) 
    _FormerRectangle = Me._Rectangle 
    End Sub 

    Public ReadOnly Property DisplayRectangle() As Rectangle 
    Get 
     Return _Rectangle 
    End Get 
    End Property 

    Public Property Location() As Point 
    Get 
     Return _Rectangle.Location 
    End Get 
    Set(ByVal value As Point) 
     _Rectangle.Location = value 
    End Set 
    End Property 

    Public Property Size() As Size 
    Get 
     Return _Rectangle.Size 
    End Get 
    Set(ByVal value As Size) 
     _Rectangle.Size = value 
    End Set 
    End Property 

    Public Property Parent() As Control 
    Get 
     Return _Parent 
    End Get 
    Set(ByVal value As Control) 
     If _Parent IsNot value Then 
     _Parent = value 
     OnParentChanged(Me, EventArgs.Empty) 
     End If 
    End Set 
    End Property 

    Overridable Sub OnParentChanged(ByVal sender As Object, ByVal e As EventArgs) 
    RaiseEvent ParentChanged(sender, e) 
    End Sub 

End Class 

EDIT3

位置示例:

Public Property Location() As Point 
    Get 
     Return _Rectangle.Location 
    End Get 
    Set(ByVal value As Point) 
     If _Parent IsNot Nothing Then 
     _Parent.Invalidate(_Rectangle, False) ' 1st Call with former ' 
     End If 
     _Rectangle.Location = value 
     If _Parent IsNot Nothing Then 
     _Parent.Invalidate(_Rectangle, False) ' 2nd Call with new ' 
     _Parent.Update() 
     End If 
    End Set 
    End Property 

不工作...

+0

我認爲你在錯誤的時間無效。讓系統爲你調用Paint(),並通過Parent.Invalidate()和Parent.Update()來控制系統。此場景運行後,添加功能並測試性能。 – Humberto 2010-06-14 14:12:27

+0

@Humberto:那麼,我應該在哪裏調用Invalidate + Update? – serhio 2010-06-14 14:15:03

+0

在幹部狀態發生變化時調用它們 - 「位置」和「大小」屬性。 – Humberto 2010-06-14 14:19:19

回答

2

鉤住Cadre類到Paint事件_Parent構件的:在其位置,大小,內容等等

Public Property Size() As Size 
    Get 
     Return _Rectangle.Size 
    End Get 
    Set(ByVal value As Size) 
     _Rectangle.Size = value 

     If _Parent IsNot Nothing Then 
      _Parent.Refresh() 
     End If 
    End Set 
End Property 

Public Property Parent() As Control 
    Get 
     Return _Parent 
    End Get 

    Set(ByVal value As Control) 
     If _Parent IsNot Nothing Then 
      RemoveHandler _Parent.Paint, AddressOf Me.Cadre_Paint 
     End If 

     _Parent = value 

     If _Parent IsNot Nothing Then 
      AddHandler _Parent.Paint, AddressOf Me.Cadre_Paint 
     End If 
    End Set 
End Property 

Private Sub Cadre_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) 
    Dim g As Graphics = e.Graphics 
    g.DrawRectangle(Pens.Black, Me._Rectangle) 
End Sub 

Refresh()父控制時Cadre變化的點擊事件被以類似的方式處理。爲_Parent.MouseDown事件添加一個處理程序,並檢查鼠標座標是否在Cadre之內。檢查Control.MouseDown瞭解更多信息。

+0

你有什麼想法:'Private WithEvents _Parent As Control'和'Private Sub DrawInternal(ByVal sender As Object,ByVal e As PaintEventArgs)Handles _Parent.Paint' – serhio 2010-06-14 13:31:44

+0

不知道該怎麼想,因爲我不是VB人! – Humberto 2010-06-14 13:35:04

+0

我相信我應該刷新父母的前一個區域,而不是所有的父母。想象一下,有一百萬幹部是不會改變的父母......有沒有這樣的可能性? – serhio 2010-06-14 13:40:21