John Oliver (UK)MSP, VSIP


Hi ALL,

I've create a CLASS where it uses the TYPEOF statement to determine what the object passed to it is, e.g.

If TypeOf(myObject) Is PictureBox Then

'some code.

ElseIf TypeOf(myObject) Is Panel Then

'same code as above only "operating on a Panel"

'with the CreateGraphics.DrawLine method

EndIf

Can i get this to work on any gui object without IF statements or SELECT CASE swtching

If so how please

I have thought of a TRY -- END TRY block but is that an "ok" or acceptable way of handling any FORM gui object

Do they all support the CreateGraphics.DrawLine method

Regards,

S_DS




Re: Polymorphism? How can you avoid "switch" statements?

Derek Smyth


Hey man,

Had a look and the Control base type that all windows controls inherit from and it does support the CreateGraphics methods. Instead of passing a type of object pass a type of System.Windows.Forms.Control instead and thats all the GUI controls covered.

With the case statement, if you draw differently on different controls then I can't see how you can avoid the case statement. You need some way to say if it's a picture box draw this and if it's a panel then draw this instead. There are maybe techniques to make it smarter but no matter what way you do it there has to be a case statement.

You could pass another object into the method that helps the program decide, for example, for a panel you create your graphics object from the panel itself from an picture box you create your graphics from the image. You could pass additional information like the picture boxes image to an overloaded version of your method. Still think case statement is needed though.

I wouldn't use a try block. If you do that then your making a decision on an exception and that can be quite expensive. When an exception is created the runtime has to walk the call stack.

Hope that proves useful






Re: Polymorphism? How can you avoid "switch" statements?

Spidermans_DarkSide - VSIP

Hi,

Thanks Derek i will give that a try.

I was thinking about just one block of code so that if Microsoft add a new control in VB.Net version 12 in say 2020 then my code should be able to handle all of the gui controls regardless of the control name or type or even if a user builds a custom gui control.

I don't want to have to add a whateverControl to my code if they are added to the ide.

Regards,

S_DS







Re: Polymorphism? How can you avoid "switch" statements?

Derek Smyth

How you doin,

Gave it a bit more thought and another way you could get this working without a case statement and for all controls although it does only work if your planning to run the same drawing code for all controls is this. Create a method that accepts a delegate that creates a graphics object. People that use the code could pass the function that creates the graphics object for the control you want to draw on. In your method you call the delegate get the returned graphics object and draws with it. Maybe thats too much, I'm not sure but it will certainly be future proof.

Like this...

Code Snippet

Public Delegate Function GetGraphics() As System.Drawing.Graphics

Public Class DrawingClass

Public Sub DrawOnControl(ByVal method As GetGraphics)

Dim g As Graphics = method.Invoke()

End Sub

End Class

If you didn't want to go this way you could also create an Interface that describes the information your method needs to work. Developers would implement this interface in their classes, fill in the required data, and pass it to your method. Your method then knows what methods and information is the object being passed.






Re: Polymorphism? How can you avoid "switch" statements?

decyclone

Hi, S_DS,

See if this helps :

Public Class Form2

Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim ctrl As New Label
Dim ctrl2 As New TextBox
Dim ptr As New Painter

Try
ptr.Paint(ctrl) ' Will call Paint(Label)
ptr.Paint(ctrl2) ' Will call Paint(Object) and throws exception
Catch Ex As NotSupportedException
' Do Something
End Try
End Sub
End Class

Public Class Painter
Public Sub Paint(ByVal ctrl As Label)
'Paint on Label
End Sub

Public Sub Paint(ByVal ctrl As Panel)
'Paint on Panel
End Sub

Public Sub Paint(ByVal ctrl As PictureBox)
' Paint on PictureBox
End Sub

Public Sub Paint(ByVal ctrl As Object) ' Can replace Object with Control
Throw New NotSupportedException()
End Sub
End Class





Re: Polymorphism? How can you avoid "switch" statements?

Spidermans_DarkSide - VSIP

Hi ALL,

I tried this>>

I've tried the following and it works without an exception thrown.

Any ideas why a Timer as Timer1 does not throw an exception

Regards,

S_DS

____________________________________________

'Add an imports statement.

'The previous project name becomes the NAMESPACE.

'The CLASS name is after the dot.

Imports Star_On_A_Wotsit.Star

Public Class Form1

Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click

Dim myPen As New Pen(Color.Turquoise)

'Draw a star with myPen, pen Width is 10 pixels,

' at 100,100

' size of 50 pixels with 10 radial arms.

newStar(PictureBox1, myPen, 10, 100, 100, 50, 10)

End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Timer1.Interval = 1000

Timer1.Start()

End Sub

Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick

Me.Text = Now.ToLongDateString & " " & Now.ToLongTimeString

End Sub

End Class

with the TIMER an exception is not thrown, any ideas why

In other words try this into the code above instead>>

newStar(Timer1, myPen, 10, 100, 100, 50, 10)

My DLL project name is called Star_On_A_Wotsit hence the namespace name in the IMPORTS statement above.

Here is the STAR CLASS code if you want to play with it >>

Public Class Star

'Pass an object such as a PICTUREBOX with a PEN of a WIDTH

'with myX1,myY1 as the star centre and a SIZE in pixels

'with however many radial arms you want as numOfArms.

Public Shared Sub newStar _

(ByVal obj As Object, _

ByVal somePen As Pen, _

ByVal width As Integer, _

ByVal myX1 As Integer, _

ByVal myY1 As Integer, _

ByVal Size As Integer, _

ByVal numOfArms As Integer)

'Set the Pen width.

With somePen

.Width = width

End With

'X1,Y1 hold the calculated points.

Dim x1 As Integer

Dim y1 As Integer

'Count is used in a FOR NEXT loop.

Dim count As Double

'Create a variable to hold 2 times Pi

Dim twoPi As Double = 2 * Math.PI

'Now draw the STAR!!

For count = 0 To twoPi Step twoPi / numOfArms

x1 = Size * Math.Sin(count) + myX1

y1 = Size * Math.Cos(count) + myY1

obj.CreateGraphics.DrawLine(somePen, x1, y1, myX1, myY1)

Next

End Sub

End Class






Re: Polymorphism? How can you avoid "switch" statements?

Spidermans_DarkSide - VSIP

Hi Derek,

I discovered i don't need a switch statement.

See my code above.

If any object doesn't support the CreateGraphics.Drawline method then my CLASS code, i guess, is tested by the compiler and as a Timer does not have that method the line is simply skipped. That is what it looks like.

Regards,

S_DS






Re: Polymorphism? How can you avoid "switch" statements?

decyclone

I tried the code and it gives me the MissingMemberException with message as 'Public member 'CreateGraphics' on type 'Timer' not found.'.

I tried the following code :

Star.newStar(Label1, New Pen(Color.Black), 100, 10, 10, 100, 5)
Star.newStar(Timer1, New Pen(Color.Black), 100, 10, 10, 100, 5)


And it did not draw the start pretty well (
I must have supplied wrong values for arguments) but other than that it worked well, I mean threw an exception for Timer object.





Re: Polymorphism? How can you avoid "switch" statements?

SJWhiteley

If you had Option Strict On, you would get a design time error. Likewise, the conversion from a double to integer would also cause an error. There are very few reasons you'd need this off (there are some), but to eliminate potential bugs, it should always be set to on.

Tools -> Options -> Projects and Solutions -> VB Defaults. Turn both Explicit and Strict On.

If it needs to be turned off for some reason, then the lines can be placed at the top of the file turning them off.






Re: Polymorphism? How can you avoid "switch" statements?

Spidermans_DarkSide - VSIP

decyclone wrote:
I tried the code and it gives me the MissingMemberException with message as 'Public member 'CreateGraphics' on type 'Timer' not found.'.

I tried the following code :

Star.newStar(Label1, New Pen(Color.Black), 100, 10, 10, 100, 5)
Star.newStar(Timer1, New Pen(Color.Black), 100, 10, 10, 100, 5)


And it did not draw the start pretty well (
I must have supplied wrong values for arguments) but other than that it worked well, I mean threw an exception for Timer object.

Hi decyclone,

I'm not suprised with a line width of 100 for the pen, try a width of say 5.

Which version of Visual Studio or Express edition are you using

I tried this in "VB9" the codename Orcas Express Edition and i didn't get an exception.

Labels support the CreateGraphics method in that edition but the code didn't do anything!!

See the bottom of this page for an image file of Orcas Express >>

http://msdn.microsoft.com/vstudio/express/future/downloads/default.aspx

You can have Express editions, Studio 2003 and Studio 2005 all installed at once.

I also have Frameworks 1.1, 2.0, 3.0 and 3.5 ( pre-release version ) all installed.

1.1 hotFix also installed.

See this screenshot.>>

http://i13.photobucket.com/albums/a272/u-might-want-this/FrameWorks.jpg

Regards,

S_DS






Re: Polymorphism? How can you avoid "switch" statements?

Spidermans_DarkSide - VSIP

Hi,

Opinions on this version then please

SJ, I forgot to test with the OPTIONS on, there is a NEW one in ORCAS ( Option Infer ).

Regards,

S_DS

Public Class Star

'Pass an object such as a PICTUREBOX with a PEN of a WIDTH

'with myX1,myY1 as the star centre and a SIZE in pixels

'with however many radial arms you want as numOfArms.

Public Shared Sub newStar _

(ByVal obj As Object, _

ByVal somePen As Pen, _

ByVal width As Integer, _

ByVal myX1 As Integer, _

ByVal myY1 As Integer, _

ByVal Size As Integer, _

ByVal numOfArms As Integer)

'Set the Pen width.

With somePen

.Width = width

End With

'X1,Y1 hold the calculated points.

Dim x1 As Integer

Dim y1 As Integer

'Count is used in a FOR NEXT loop.

Dim count As Double

'Create a variable to hold 2 times Pi

Dim twoPi As Double = 2 * Math.PI

'Now draw the STAR!!

Try

For count = 0 To twoPi Step twoPi / numOfArms

x1 = Size * Math.Sin(count) + myX1

y1 = Size * Math.Cos(count) + myY1

obj.CreateGraphics.DrawLine(somePen, x1, y1, myX1, myY1)

Next

Catch

Throw New Exception(" 'STAR' method not available for that TYPE of object.")

End Try

End Sub

End Class






Re: Polymorphism? How can you avoid "switch" statements?

decyclone

Hi Spidey,
I work on VS 2005, and here it works well with Option Strict Off, but gives a couple of error when Strict is On. And the following line :

obj.CreateGraphics.DrawLine(somePen, x1, y1, myX1, myY1)

won't work with Option Strict On because the type of obj is Object and so it will be late binding.





Re: Polymorphism? How can you avoid "switch" statements?

Spidermans_DarkSide - VSIP

decyclone wrote:
Hi Spidey,
I work on VS 2005, and here it works well with Option Strict Off, but gives a couple of error when Strict is On. And the following line :

obj.CreateGraphics.DrawLine(somePen, x1, y1, myX1, myY1)

won't work with Option Strict On because the type of obj is Object and so it will be late binding.

Hi,

What would you suggest then

I was thinking of building up a library of 'new graphics routines' which are not curently in Visual Studio or the Express editions.

If i do then do you know how i can make code into an "add-in" at all please

Regards,

S_DS






Re: Polymorphism? How can you avoid "switch" statements?

Spidermans_DarkSide - VSIP

Hi,

The CLASS code is now as per the following code, as per Dereks' earlier suggestion.

I guess my NEW exception here may never be thrown now

Regards

S_DS

Public Class Star

'Pass an object such as a PICTUREBOX with a PEN of a WIDTH

'with myX1,myY1 as the star centre and a SIZE in pixels

'with however many radial arms you want as numOfArms.

Public Shared Sub newStar _

(ByVal obj As System.Windows.Forms.Control, _

ByVal somePen As Pen, _

ByVal width As Integer, _

ByVal myX1 As Integer, _

ByVal myY1 As Integer, _

ByVal Size As Integer, _

ByVal numOfArms As Integer)

'Set the Pen width.

With somePen

.Width = width

End With

'X1,Y1 hold the calculated points.

Dim x1 As Integer

Dim y1 As Integer

'Count is used in a FOR NEXT loop.

Dim count As Double

'Create a variable to hold 2 times Pi

Dim twoPi As Double = 2 * Math.PI

'Now draw the STAR!!

Try

For count = 0 To twoPi Step twoPi / numOfArms

x1 = Size * Math.Sin(count) + myX1

y1 = Size * Math.Cos(count) + myY1

obj.CreateGraphics.DrawLine(somePen, x1, y1, myX1, myY1)

Next

Catch

Throw New Exception(" 'STAR' method not available for that TYPE of object.")

End Try

End Sub

End Class






Re: Polymorphism? How can you avoid "switch" statements?

decyclone

Hi,

Which version of .Net do you wish to create the library for Because Orcas provides some classes for managing Application Plug-ins. And I strongly believe using switch-case/if-else/function-overloading/control-adapters would be better to use than using late binding in Visual Basic. That is an older concept and I know it's easy to use, but still if I had no choice, I'd choose using Reflection over late binding.

Other than that, can you explain which kind of behavior/functionality are you trying to add to the current library which is not currently available