There *has* to be a more compact way to do this...

C

Confessor

I've heard that 'brevity is the ultimate bugkiller,' and I can't help but
feel that portions of my code could be a bit more brief.

I have 85 different labels comprising a type of 'gameboard.'

Upon initialization in the code generated by the form designer, each
label receives properties as follows.

Me.Labelx.BackColor = System.Drawing.Color.White
Me.Labelx.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
Me.Labelx.Location = New System.Drawing.Point(x, y)
Me.Labelx.Name = "Labelx"
Me.Labelx.Size = New System.Drawing.Size(32, 32)
Me.Labelx.TabIndex = x

As you might expect, only the TabIndex, Name, and Location properties
vary per label. If anybody can tell me how to make it so I can set the
three static properties only *once* for all eighty-five labels, that
would probably save me ~200 lines of code right there.

Similarly, specific events/procedures scattered throughout the program
modify all 85 gameboard labels in the same way. Currently, I have to do
something like this:

Label1.Text = ""

For all 85 labels...

Or, when I pass label status to my variables for in-depth analysis, I
currently have to

Tile(1).Color = Label1.BackColor

For all 85 labels.

Any help would be appreciated.
 
C

Cliff Cavin

Confessor,

I built a scrabble gameboard using label controls.
The label controls are all square shaped, to represent tiles.
The only real "trick" to this is the AddHandler statement.

Good luck,,,,,, Cliff


Dim Tile(14, 14) As Label


Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Dim R, C As Int16
Dim TileHeight As Int16 = 40
Dim TileWidth As Int16 = 40
Dim F As New Font("Courier New", 18, FontStyle.Bold)
For R = 0 To 14
For C = 0 To 14
Tile(R, C) = New Label
Tile(R, C).Height = TileHeight
Tile(R, C).Width = TileWidth
Tile(R, C).Top = 20 + R * TileHeight
Tile(R, C).Left = 20 + C * TileWidth
Tile(R, C).BorderStyle = BorderStyle.FixedSingle
Tile(R, C).Font = F
Tile(R, C).TextAlign = ContentAlignment.MiddleCenter
Tile(R, C).Name = Format(R, "00") & Format(C, "00")
Me.Controls.Add(Tile(R, C))
Tile(R, C).Visible = True
AddHandler Tile(R, C).Click, AddressOf Tiles_Click
Next
Next
End Sub

Private Sub Tiles_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
'The Sender.Name contains the subscript of the label control
'in the format "RRCC".
Dim R, C As Int16
Dim Str As String
Str = sender.name
R = Val(Str.Substring(0, 2))
C = Val(Str.Substring(2, 2))
'
' Now, you can reference the tile by: Tile(R,C)
' Such as: Tile(R,C).Text = "Something...."
'
'
'
End Sub
 
C

Confessor

Confessor,

I built a scrabble gameboard using label controls.
The label controls are all square shaped, to represent tiles.
The only real "trick" to this is the AddHandler statement.

Good luck,,,,,, Cliff

Very grateful for your help, Cliff, as it seems to have brought my line count under 1000, even with form initialisation
included.

As a side note, I included the creation of the 85-member makeshift control array in the InitializeComponent Sub, and
though it seems to work like a charm during runtime, it spits out errors when I switch back to design view. Was this why
you placed your control creation routine in Form.Load?

Unfortunately, the gameboard for my project is not a perfect square or rectangle, so I'm stuck with using a manual array &
defining control position manually.

Neat trick with that macro for the "Name" property. I would never have come up with that on my own.

Thank you again,
The Confessor.
 
J

Jay B. Harlow [MVP - Outlook]

Confessor,
Have you considered creating a custom control?

Create a GameBoardLabel control that inherits from Label, within the
GameBoardLabel constructor have it set the common properties to the new
"default" value, override (shadow) any properties that have a new default,
to inform the designer of the new default (one valid use of Shadow). If you
have "common" event handlers have GameBoardLabel override those events...

Then on your form instead of using a Label control, use a GameBoardLabel
control instead.

If you need to update all GameBoardLabel controls en masse, I would consider
manually defining an array of them in my form & using a For Each loop. If I
have a number of operations that need to occur en masse, I would consider
defining a GameBoardLabelCollection that has the all the operations
defined...


Something like:

Option Strict On
Option Explicit On

Imports System.ComponentModel

Public Class GameBoardLabel
Inherits Label

Public Sub New()
Me.BackColor = Color.White
Me.BorderStyle = BorderStyle.FixedSingle
Me.Size = New Size(32, 32)
End Sub

<DefaultValue(GetType(Color), "White")> _
Public Overrides Property BackColor() As Color
Get
Return MyBase.BackColor
End Get
Set(ByVal value As Color)
MyBase.BackColor = value
End Set
End Property

<DefaultValue(GetType(BorderStyle), "FixedSingle")> _
Public Overrides Property BorderStyle() As BorderStyle
Get
Return MyBase.BorderStyle
End Get
Set(ByVal value As BorderStyle)
MyBase.BorderStyle = value
End Set
End Property

Protected Overrides ReadOnly Property DefaultSize() As Size
Get
Return New Size(32, 32)
End Get
End Property

Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
MyBase.OnClick(e)
If MyBase.BackColor.Equals(Color.White) Then
MyBase.BackColor = Color.Black
Else
MyBase.BackColor = Color.White
End If
End Sub

End Class

In the above example any Click event by any GameBoardLabel (the OnClick
override above) will cause the back ground color of that control to toggle
between white & black.

Hope this helps
Jay
 
C

Confessor

How about taking a crack at using one control for the whole thing, and
using GDI+ to paint each element?

I'm going to have to research the fundamentals of control creation. My last
prolonged exposure to Visual Basic was circa 3.0, and even then I only used
standard controls.
Check out the "flyweight" design pattern. Sorry, these are the best
links I could find -

http://www.learnvisualstudio.net/videos/072803_GoF_Structural_Patterns_
Flyweight.htm http://www.dofactory.com/Patterns/PatternFlyweight.aspx

I also recommend the book "Design Patterns: Elements of Reusable
Object Oriented Software".

I will keep those references on-hand for use the next time I have some
slack in my cash flow.

Thank you, Bob,
The Confessor
 
C

Confessor

Confessor,
Have you considered creating a custom control?

I've never created a custom control before, since I assumed that it was a
fantastically difficult process (and perhaps it was circa VB 3.0). I *will* take a
second look at custom control creation, though. Thank you for the heads up.

Thanks Again, Jay,
The Confessor
 
J

Jay B. Harlow [MVP - Outlook]

Confessor
With inheritance creating a specialized version of a control, such as
GameBoardLabel is super easy, did you look at the code that I included?

Creating GameBoardLabel also promotes Encapsulation, as all the logic
specific to a GameBoardLabel is encapsulated within the control itself.

You can also start with Control or UserControl, however they can be more
work. I normally start with the control that is most like the control I
need...


If memory serves VB3 basically required you create a custom control using
C++.


Inheritance and Encapsulation are major tenants of OOP (Object Oriented
Programming). The other major two tenants are Abstraction & Polymorphism.

Robin A. Reynolds-Haertle's book "OOP with Microsoft Visual Basic .NET and
Microsoft Visual C# .NET - Step by Step" from MS Press provides a good intro
on how to do OOP in VB.NET.

Hope this helps
Jay
 
J

Jay B. Harlow [MVP - Outlook]

Confessor,
I should add, that knowing & using OO well can significantly reduce the
amount of code in your program, by reducing duplication of code...

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top