Creating a DLL for Drawing a Rectangle in VB.Net 2010

812 views Asked by At

About the Project

I have a form that has three buttons, each add a rectangle to the drawing area of the form (SplitContainer.Panel2). As you can see, adding this code multiple times to different buttons becomes very tedious and cluttering. I was wanting to know if I could call a function to perform this code. I know how to create functions and how to call them, but I do not understand how to reference the controls within the forms (e.g the panel).

Screenshot of the project (after clicking a few buttons):

http://i61.tinypic.com/2q9kr5y.png (low rep, had to use URL)

My Code Called From the "Add Move" Button:

Dim objGraphics As Graphics
    Dim rect = New Rectangle(intX, intY, 50, 50)
    Dim objFont As Font
    Dim objFont2 As Font
    Dim intFontSize As Integer = 12
    Dim intTextX As Integer = intX
    Dim intTextY As Integer = intY

    ' Create a graphics object using the memory bitmap
    objGraphics = Graphics.FromImage(m_objDrawingSurface)

    objGraphics.FillRectangle(Brushes.Plum, rect)
    objGraphics.DrawRectangle(Pens.Black, rect)

    objFont = New System.Drawing.Font("Arial", intFontSize, _
                                      FontStyle.Bold Or FontStyle.Italic)

    objFont2 = New System.Drawing.Font("Arial", intFontSize - 5, _
                                      FontStyle.Bold Or FontStyle.Italic)

    ' Draw user's text
    objGraphics.DrawString("Move", objFont, _
                           System.Drawing.Brushes.White, intTextX, intTextY)

    objGraphics.DrawString("(" & MousePosition.X & ", " & MousePosition.Y & ")", objFont2, _
                           System.Drawing.Brushes.White, intTextX, intTextY + 17)


    ' Clean up
    objGraphics.Dispose()

    ' Force the form to paint itself. This triggers the Paint Event
    SplitContainer1.Panel2.Invalidate()

    intX += 50

    If intX >= SplitContainer1.Panel2.Width Then
        intY += 50
        intX = 0
    End If

The Goal

I want to be able to separate my code in a more modular fashion. I'm coming from C++ where modulation is everything, and without here, my code grows enormously. Any help would be greatly appreciated.

EDIT: To be straight forward, how can I replicate this code in a Class Library or DLL so that I can use it in a modular fashion?

1

There are 1 answers

1
Karl Stephen On BEST ANSWER

A DLL is a bit overkill IMHO.

But I'm wondering : if you can create a function, you should be able to compile a DLL containing that function... What is the issue ?

Creating a Function is very simple, assuming your function gets access to the control object, ie, the SplitContainer.Panel2, or any other defined control (Button, Panel, etc.) you want to alter the painting. ie, you have to pass that control to the function.

Public Function DrawRectangleOn(ByRef SplitContainerPanel As SplitterPanel) As Boolean
    ' ... Do the drawings.

If you have some layout conditions, you must pass the criterias to control those conditions aswell.

Public Function DrawRectangleOn( _
    ByRef SplitContainerPanel As SplitterPanel, _
    ByVal PlotX As Int32, _
    ByVal PlotY As Int32, _
    ByVal FrameColor As Color, _
    ByVal FrameBackground As Color, _
    ByVal Caption As String, _
    ByVal MousePosX As Int32, _
    ByVal MousePosY As Int32, _
    ByVal ... etc. etc. etc.) As Boolean
    ' ... Do the drawings.

You don't have to use a Function (in VB meaning) but a Method if you don't need to get a return/result value of the operation :

Public Sub DrawRectangleOn( ... )

One thing however, your Function/Method should know what's the Type of the object to manipulate. That means, if you want to manipulate several controls, you'll have to :

a) either make several function with stronged types parameters :

Public Function DrawRectangleOn(ByRef SplitContainerPanel As SplitterPanel, ...)
Public Overloads Function DrawRectangleOn(ByRef ControlButton As Button, ...)
Public Overloads Function DrawRectangleOn(ByRef ControlPanel As Panel, ...)

b) or define the type of the object inside that function by passing a weak type parameter :

Public Function DrawRectangleOn(ByRef PassedControl As Control, ...)
    Select Case True
        Case TypeOf(PassedControl) Is SplitterPanel:
            Dim ControlSplitterPanel As SplitterPanel = _
                DirectCast(PassedControl, SplitterPanel)
            ' ... Manipulate a SplitterPanel here.

            Return True

        Case TypeOf(PassedControl) Is Button:
            Dim ControlButton As Button = _
                DirectCast(PassedControl, Button)
            ' ... Manipulate a Button here.

            Return True

        Case Else:
            Throw New ArgumentException("Unable to handle Object of type " + PassedControl.GetType().ToString())

    End Select
End Function

If you create a DLL, I'm sure you're aware that each time you make changes to the source of that DLL, you'll have to recompile it and redistribute it in order to update any project/solution/application using it. A DLL ought to be the ultimate goal of the work, and should be well envisioned before writing the code, not decided as a requirement you would think of in the middle of the coding.

That's why I said a DLL is a bit overkill XD. DLLs (should) have version numbering and should backward compatibles, otherwise you'll have unpredictable behaviours in previous applications using them...


I'm somewhat curious : what do you want to do with all that custom drawn frames ?

All you're doing now is drawing on the control. But it would make sense to be able to click on the rectangles/frames and call specific methods/functions... it would also make sense to notify the user when the mouse is above one frame, like changing the frame background for example...

=> I'm not telling you to implement the above. You don't have to answer the question above, what you want to do is up to you. I'm just telling you to define every feature that should be considered before deciding what tools you're going to use (ie how are you going to write code, which components to use, etc.)

There are other approaches you can experiment :

  • Create a CustomSplitContainer that inherits from SplitContainer. Then handle the UI inside by adding public methods and function and properties and events.
  • Create a UserControl from scratch with a SplitContainer then handle the UI behaviour inside, or just like above, create public members to be able to control the UI externaly.
  • Create Control Extensions (System.Runtime.CompilerServices - User defined Functions and Methods extended on an instanciated object/control - requires the appropriate dotNet Framework)
  • Create a Public Module with members you can call from anywhere in your project.
  • Create a custom Class which constructor gets reference to the Control to handle. Then, handle every click, mouseover, etc. and draw the appropriate UI from inside that class.
  • (... like using delegates)

The custom class example is the one I'm using most : I know everything I need is within that class that does only what it's supposed to do with strong typed members. And there are Control Members I usually don't need to take care of, while, for precise and repetitive tasks like altering the UI, it's easier to encapsulate the control in a class, and create persistant properties, methods, functions and events. Upon instanciation, AddHandler is very usefull to capture mouse and keyboard inputs, handle custom drag/drops, etc. (However, those custom classes should be properly destroyed when not required anylonger)


Anyway, you can write the code of a DLL whatever your choice.

  • Create a project by selecting "Class Library" <- this would answer your question..
  • Copy the code you've done in that library project with the appropriate or required changes (that's what I said above : you must pass any required references to the functions of that DLL)
  • Build it
  • Locate the DLL in your Debug/Release folder of current project
  • Copy it to your final project that will use the DLL
  • Imports the reference the usual way.

or just add a class library sub project in your solution.

Just make sure to select the best approach to reach your goal. You can always add links to classes/modules sources in any project/solution and reuse an already available code without creating a DLL ! The code is just compiled in your executable.

PS : by the way, if you were/are C++, I would advise you to go on with C#.