Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Go Back  Xtreme Visual Basic Talk > > > Weird bug, Drawrectangle won't work just the first time it's called.


Reply
 
Thread Tools Display Modes
  #1  
Old 05-13-2014, 11:27 PM
Zerocyde Zerocyde is offline
Freshman
 
Join Date: May 2007
Posts: 32
Default Weird bug, Drawrectangle won't work just the first time it's called.


So, I have an array of this simple class...

Quote:
Private Class RoomClass
Inherits Windows.Forms.Button

Public Sub New(ByVal x As Long, ByVal y As Long, ByVal i As Integer)
Me.BackColor = Color.WhiteSmoke
Me.FlatStyle = Windows.Forms.FlatStyle.Flat
Me.FlatAppearance.BorderColor = Color.Black
Me.FlatAppearance.MouseDownBackColor = Color.LightGray
Me.FlatAppearance.MouseOverBackColor = Color.WhiteSmoke
Me.Width = 60
Me.Height = 60
Me.Left = x
Me.Top = y
Me.FlatAppearance.BorderSize = 0
Me.Text = i
Me.DrawBorder()
ShipForm.Controls.Add(Me)
End Sub

Public Sub DrawBorder()
Dim g As Graphics = ShipForm.CreateGraphics
Dim Pen As New Pen(Color.Black, 4)
g.DrawRectangle(Pen, Me.Left, Me.Top, Me.Width, Me.Height)
g.Dispose()
End Sub
End Class
I redim and add a new one of these every time you double click on the form. The FIRST ONE will NOT draw the black border, but every one after that will.

Only clue I got is that if I comment out the "shipform.controls.add(me)" it draws the black border every time, even the first time. It's gotta be something simple I'm missing, and ideas?
Reply With Quote
  #2  
Old 05-14-2014, 01:28 AM
PlausiblyDamp's Avatar
PlausiblyDampWeird bug, Drawrectangle won't work just the first time it's called. PlausiblyDamp is offline
Ultimate Contributor

Forum Leader
* Expert *
 
Join Date: Nov 2003
Location: Newport, Wales
Posts: 2,058
Default

Why is the button even calling ShipForm.Controls.Add(Me) anyway? The form should be responsible for this, not the button itself. In fact if you are adding the button via the designer then this is automatically taken care of anyway.
__________________
Intellectuals solve problems; geniuses prevent them.
-- Albert Einstein

Posting Guidelines Forum Rules Use the code tags
Reply With Quote
  #3  
Old 05-14-2014, 09:13 AM
passel's Avatar
passelWeird bug, Drawrectangle won't work just the first time it's called. passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Getting the form's graphics using CreateGraphics is only drawing on the screen. It is not persistent, and you shouldn't be using CreateGraphics on Forms and Controls as a general rule.
Whenever the form decides it needs to redraw itself (i.e. try dragging a window across your form displaying some of these buttons and you will see the borders wiped out), the Paint event will be fired and a Graphics object to do the drawing with is passed to the Paint event handler. You use this graphics object to redraw all the borders (so the DrawBorder sub was changed to accept a graphics object passed to it).

The reason the first is erased is because after adding the first control to the form, the form decided it needed to redraw itself, so the border was "wiped out". Apparently, at least temporarily, added additional buttons didn't trigger the form to redraw all of itself.

To make the borders persistent, the border drawing should be done in the Paint event of the form.

Here's a quick modification of your code, with the additional things added you mentioned, i.e. double clicking on the form to create a new button. I chose to use a list to hold references to the buttons, rather than redim an array.
I have Option Strict on, so changed the New sub's x and y parameters to Integer as Long does not match the type of .Left and .Top.
Also added the .ToString to i (i.ToString) since Option Strict requires explicit conversion of the variable to a string when assigning to the .Text property.
Don't need to call DrawBorder from the New sub, since that will be taken care of by causing the Form to refresh itself using Invalidate.

p.s. In consideration about what PlausiblyDamp said about referencing the form in the class. If you wanted to use this class on another form, or project, you would have to change the form's instance name. The class should not have knowledge of things outside its scope hardcoded in the class. That type of information, if needed, should be passed to the class or provided through some indirect method. You should not have to edit the class to make it work with a specific form.
So, given that, the line that adds the newly created object to the form's controls is added to the Form's code, just after it creates the object.
Code:
buttonList.Add(New RoomClass(e.X, e.Y, RoomNumber)) 'create button, add to list
Controls.Add(buttonList.Last)  'also add it to Form's controls
Complete listing.
Code:
Public Class ShipForm

  Private Class RoomClass
    Inherits Windows.Forms.Button

    Public Sub New(ByVal x As Integer, ByVal y As Integer, ByVal i As Integer)
      Me.BackColor = Color.WhiteSmoke
      Me.FlatStyle = Windows.Forms.FlatStyle.Flat
      Me.FlatAppearance.BorderColor = Color.Black
      Me.FlatAppearance.MouseDownBackColor = Color.LightGray
      Me.FlatAppearance.MouseOverBackColor = Color.WhiteSmoke
      Me.Width = 60
      Me.Height = 60
      Me.Left = x
      Me.Top = y
      Me.FlatAppearance.BorderSize = 0
      Me.Text = i.ToString
    End Sub

    Public Sub DrawBorder(g As Graphics)
      Dim Pen As New Pen(Color.Black, 4)
      g.DrawRectangle(Pen, Me.Left, Me.Top, Me.Width, Me.Height)
      Pen.Dispose()
    End Sub
  End Class

  Dim buttonList As New List(Of RoomClass)

  Private Sub ShipForm_MouseDoubleClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDoubleClick
    Static RoomNumber As Integer
    RoomNumber += 1
    buttonList.Add(New RoomClass(e.X, e.Y, RoomNumber))
    Controls.Add(buttonList.Last)

    Me.Invalidate()
  End Sub

  Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    For Each btn As RoomClass In buttonList
      btn.DrawBorder(e.Graphics)
    Next
  End Sub
End Class
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 05-14-2014 at 12:17 PM.
Reply With Quote
  #4  
Old 05-14-2014, 11:50 AM
passel's Avatar
passelWeird bug, Drawrectangle won't work just the first time it's called. passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Of course, having to draw the border on the form itself is probably not the best approach.
The control being added should probably draw the border as part of itself.
I haven't had a lot of experience creating controls, so won't bother to try now, but one way to modify your existing class is to add a panel to parent the button. That way you can offset the button within the panel and draw the border in the panel (which is part of your class), rather than have to draw it externally on the form. That way you don't have to add extra code to the form's paint event in order to use the class.
Added the Paint event handler for the panel, and a Button_Click event for the button.
Code:
Public Class ShipForm

  Private Class RoomClass
    Inherits Windows.Forms.Button
    Private WithEvents pnl As New Panel

    Public Sub New(ByVal x As Integer, ByVal y As Integer, ByVal i As Integer)
      Me.BackColor = Color.WhiteSmoke
      Me.FlatStyle = Windows.Forms.FlatStyle.Flat
      Me.FlatAppearance.BorderColor = Color.Black
      Me.FlatAppearance.MouseDownBackColor = Color.LightGray
      Me.FlatAppearance.MouseOverBackColor = Color.WhiteSmoke
      Me.Width = 60
      Me.Height = 60
      Me.Left = 4
      Me.Top = 4
      Me.FlatAppearance.BorderSize = 0
      Me.Text = i.ToString
      Me.Parent = pnl
      pnl.Visible = True
      pnl.Left = x
      pnl.Top = y
      pnl.Width = 68
      pnl.Height = 68
    End Sub

    Private Sub pnl_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles pnl.Paint
      Dim Pen As New Pen(Color.Black, 4)
      e.Graphics.DrawRectangle(Pen, Me.Left, Me.Top, Me.Width, Me.Height)
      Pen.Dispose()
    End Sub

    Private Sub btn_Click(sender As Object, e As System.EventArgs) Handles Me.Click
      Debug.Print("You pressed button " & Me.Text)
    End Sub

  End Class

  Dim buttonList As New List(Of RoomClass)


  Private Sub ShipForm_MouseDoubleClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDoubleClick
    Static RoomNumber As Integer
    RoomNumber += 1
    buttonList.Add(New RoomClass(e.X, e.Y, RoomNumber))
    Controls.Add(buttonList.Last.pnl)
    Me.Invalidate()
  End Sub

End Class
[/code]
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 05-14-2014 at 12:18 PM.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called. Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
 
Weird bug, Drawrectangle won't work just the first time it's called.
Weird bug, Drawrectangle won't work just the first time it's called.
 
-->