在 .NET 中绘制矩形

发布于 2024-09-05 13:16:53 字数 4255 浏览 4 评论 0原文

我尝试编写一个类,将其自身绘制在控件上(.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 绘制内部
  • 是否可以有 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

不起作用...

I try to write a class that will draw itself on a control(.NET 2). But this "thing" does not repaint itself properly(does not invalidate the parent as it should).

Here is the usage:

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

Here is the code:

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
  • What I am doing wrong?
  • What is better: use private Graphic g and
    set it only once when parent changed,
    or create g at every
    DrawInternal?
  • Is it possible to have on it the Click event?

CADRE v2 (after Humberto suggestions):

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

Location Example:

  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

Does not work...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坏尐絯 2024-09-12 13:16:53

Cadre 类挂钩到 _Parent 成员的 Paint 事件:

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 了解更多信息信息。

Hook the Cadre class to the Paint event of the _Parent member:

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() the parent control upon Cadre changes on its location, size, contents etc.

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

The click event is handled in a similar manner. Add a handler for the _Parent.MouseDown event, and check if the mouse coordinates are inside your Cadre. Check Control.MouseDown for more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文