2010-06-14 149 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