在.NET中绘制一个矩形

时间:2010-06-14 13:11:34

标签: .net .net-2.0 gdi+

我尝试编写一个可以在控件上绘制自己的类(.NET 2 )。但是这个“东西”并没有正确地重新绘制(不会使父亲无效)。

以下是用法:

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和 当父母改变时,只设置一次, 或者每次都创建g DrawInternal
  • 是否可以使用Click事件?

CADRE v2(在Humberto建议之后):

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

不起作用......

1 个答案:

答案 0 :(得分:2)

Cadre课程挂钩到Paint成员的_Parent个事件:

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更改其位置,大小,内容等。

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

点击事件以类似的方式处理。为_Parent.MouseDown事件添加处理程序,并检查鼠标坐标是否在Cadre内。查看Control.MouseDown了解详情。