Encapsulating Controls in a Class

vendiddy

Well-known member
Joined
May 14, 2006
Messages
64
Programming Experience
1-3
I have a MustInherit class called wCommand. It's basically a class that represents a command of any type. I've made (or will make) several subclasses, like wRenameFile, wDeleteFile, wRunProgram, wOpenWebPage, wRetrieveText, etc.

The problem is that each command takes different arguments.
  • You can see the arguments 'Rename File(s)' would take from the screenshot.
  • 'Delete File(s)' would need the name of the file, its folder, and whether to delete everything in the folder that matches.
  • 'Open Web Page' would just require a URL.
  • Run program would need to know the path of the executable and its window state (minimized/maximized/hidden) ...
Because of this, I have to make a different set of controls (Text Boxes, Radio Buttons, Command Buttons, etc.) for each type of command. The question is: How do I encapsulate each set of controls in its class?

As an example, taking a look at the screenshot. If I selected 'Open Web Page' from the drop down, here is what would happen:
  • The controls from wRenameFile would be unloaded
  • The controls stored in wOpenWebPage (probably something like txtURL) would be loaded onto the form.
  • When the create command button is pushed, wOpenWebPage would read all the information from its controls and create a new instance of wOpenWebPage.
  • At this point, if .PerformCommand is called on this instance, it has the command already stored, so it knows what to do and does it. (Maybe you'd have a wCommand called OpenGoogle that launches www.google.com in Internet Explorer)
Thanks. Hope my description wasn't too long. :rolleyes:
 

Attachments

  • Controls.JPG
    Controls.JPG
    26.5 KB · Views: 53
You could make a user-control for each command, and when user select a command type in combobox you create an instance of the appropriate control and put in the form.
 
Would creating a user-control create extra compiled files? I'm trying to make my program just one executable file without any dll baggage.

I did some research and found out that you can create controls dynamically (I'm new to VB.NET).
http://www.exforsys.com/content/view/1514/350/

I think I might do this by creating the controls using code. For example, here is what I've tried (as a test):
Here is part of my wRenameCommand class:
VB.NET:
[SIZE=2][COLOR=#0000ff]Public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE][SIZE=2] WRenameFile[/SIZE]
[SIZE=2][COLOR=#0000ff]    Inherits[/COLOR][/SIZE][SIZE=2] WCommand[/SIZE]
 
[SIZE=2][COLOR=#0000ff]Shared[/COLOR][/SIZE][SIZE=2] SpecificControls(0) [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Control[/SIZE]
 
[SIZE=2]...[/SIZE]
 
[SIZE=2][COLOR=#0000ff]Public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Shared [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] InitializeControls()[/SIZE]
[SIZE=2][COLOR=#0000ff]    Dim[/COLOR][/SIZE][SIZE=2] myTextBox [/SIZE][SIZE=2][COLOR=#0000ff]As [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][SIZE=2] TextBox[/SIZE]
[SIZE=2]    SpecificControls(0) = myTextBox[/SIZE]
[SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]Public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Shared [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] PutControlsOnForm()[/SIZE]
[SIZE=2]    frmCommands.grpNewCommandFields.Controls.AddRange(SpecificControls)[/SIZE]
[SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]Public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Shared [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] ShowDebug()[/SIZE]
[SIZE=2]    MessageBox.Show(SpecificControls(0).Text)[/SIZE]
[SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE]

grpNewCommandFields is a GroupBox

And here is part of the code for frmCommands:
VB.NET:
[SIZE=2][COLOR=#0000ff]Public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE][SIZE=2] frmCommands[/SIZE]
 
...
 
 
[SIZE=2][COLOR=#0000ff]Private [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] btnShowTextBox_Click([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] btnShowTextBox.Click[/SIZE]
[SIZE=2]     WRenameFile.InitializeControls()[/SIZE]
[SIZE=2]     WRenameFile.PutControlsOnForm()[/SIZE]
[SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]Private [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][SIZE=2] btnShowDebug_Click([/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] sender [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.Object, [/SIZE][SIZE=2][COLOR=#0000ff]ByVal[/COLOR][/SIZE][SIZE=2] e [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] System.EventArgs) [/SIZE][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][SIZE=2] btnCreateCommand.Click[/SIZE]
[SIZE=2]     WRenameFile.ShowDebug()[/SIZE]
[SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#0000ff]End [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Class[/COLOR][/SIZE]

If I click on btnShowTextBox, type something into the text box that appears, and press btnShowDebug, then it displays a message box with the text I just typed in. Is creating the controls like this a good way to do this?

Sorry, I have one more question. Is there a way to run the InitializeControls() command right when the class initializes (not just an instance)? Or, would best best to run this Sub during the form_load event?

Thank you. :cool:
 
Last edited:
You would be better off designing the individual commands input forms as user-controls.

In the groupbox of your screenshot I see you have mixed two different user interface controls, those that is used to get user input to the command, and those that manages the creation of a command. You should separate these in the UI design. For instance, the Name of command, the selection of command Type, and the button to finalize the Create command, these are the three controls that manages the commands. The other controls in that groupbox as I see it are those accept input to customize a specific command, these should be put in different user-controls instead. This way you can dynamically add/remove a single control (containing the full command UI) when user selects different command types in the combobox.

All classes (inherited controls are also classes!) that belong to a single project is compiled to a single assembly file (.exe .dll). If you add a usercontrol to your application project it will compile into application.exe, if you add a usercontrol to a class library project it will compile into the classlibrary.dll.

I think you should add a class library project to your solution that contains all classes and usercontrols for your command library. I don't understand why you would object to adding a library file to your application, there is no reason not to, but several in favour. It's object oriented programming, makes it better structured and less messy to work with.

Even if you never created a usercontrol before, I would say this is the time to learn it.
 
You don't need a tutorial on UserControls. They're like a form in that they allow you to design visually but they are just like any other class, including forms, in that they allow you to hide objects inside, in this case other controls, and just expose the properties and members that you want. For instance, if you had a UserControl that contained a TextBox and all you wanted to expose of the TextBox to the outside world was its Font property you would do something like:
VB.NET:
Public Property TextFont() As Font
    Get
        Return Me.TextBox1.Font
    End Get
    Set
        Me.TextBox1.Font = value
    End Set
End Property
That's all you need to know, but that's true of any class though.
 
I was going to say something similar, but it's already said so I just add some thoughts. Creating a usercontrol is very much the same as creating a form, I have to admit although I have created a lot of usercontrols I have yet to ever read an article/tutorial about how to do it, it is just that easy! :) There are just so many things in VB/Designer you can just try out and get it working intuitively. With the context menu in Solution Explorer you can Add New Item which bring you a dialog to choose from different new items. Choose UserControl and a fresh surface is displayed. Now you select the controls you want from toolbox, same as putting them on a form. This is how you visually design your usercontrol. Same as a form if you want to access a property from another class you provide one by write one like jmcilhinneys example. Now that you have added controls and added code for any public property and/or method you want this class to have, build it, go to the form and look at the top of toolbox there your new usercontrol is listed and you can add it to the form. Same as any other control you can also add it dynamically in code. Of course there is much help in documentation if you want to read it, maybe I should too :) What I do is to open help from VS and go to index search and write "usercontrol" and get to choose from several relevant topics, walkthroughs are often good to start with.
 
Back
Top