Welcome to the third and final Windows Secrets article!
I’m Karl Moore, and today we’re taking a sneak peak at even more Windows application tips and tricks adapted from my soon-to-be-released book, VB.NET and ASP.NET Secrets.
In this article, we’ll be covering:
- How to ‘Reset’ a Form
- The Facts on Visual Inheritance
- Secrets of Working with the System Tray
- Best of All Worlds: Creating an Ultra-Thin Client
But, hold on a minute. Didn’t I just say this was the final article? Well, thankfully, the end isn’t quite nigh.
This is a twelve-part series, split into a bundle of categories which will focus on Windows applications (three parts), ASP.NET (five parts), data (three parts), and Web service secrets (figure this one out yourself). That means that next week we’ll be looking at a bundle of ASP.NET adaptations from my new book. But that’s for another article.
For now, are you sitting comfortably? Then I’ll begin…
How to ‘Reset’ a Form
If you’ve created a data entry style Windows form that needs “resetting” with each addition, the code to clear the TextBox controls, uncheck the CheckBox controls, and so on can all get a little repetitive—particularly if you have to write it for multiple forms.
That’s where the following method could prove useful. Simply pass in a form as a parameter, and it’ll reset the main data entry controls: TextBox, CheckBox, and ComboBox. You also could easily extend it to cater to RadioButton, ListBox, CheckedListBox, DomainUpDown, NumericUpDown, MonthCalendar, and DateTimePicker controls, too. To ensure flexibility, this subroutine automatically bypasses all controls with “skip” somewhere in the Tag property.
Here’s the code:
Public Sub ResetForm(ByVal FormToReset As Form) ' Resets the main data entry controls ' on the passed FormToReset Dim objControl As Control ' Loop round every control on the form For Each objControl In FormToReset.Controls ' Check we don't need to skip this control If InStr(objControl.Tag, "skip", CompareMethod.Text) = 0 _ Then If TypeOf (objControl) Is _ System.Windows.Forms.TextBox Then objControl.Text = "" ' Clear TextBox ElseIf _ TypeOf (objControl) Is System.Windows.Forms.CheckBox _ Then Dim objCheckBox As System.Windows.Forms.CheckBox _ = objControl objCheckBox.Checked = False ' Uncheck CheckBox ElseIf _ TypeOf (objControl) Is System.Windows.Forms.ComboBox _ Then Dim objComboBox As System.Windows.Forms.ComboBox _ = objControl objComboBox.SelectedIndex _ = -1 ' Deselect any ComboBox entry End If End If Next End Sub
You could use this function behind your form, as so:
The Facts on Visual Inheritance
Visual inheritance allows you to create one “master” form, then have other Windows forms inherit its layout and code. For example, you might create one master form for your application wizard, then add further wizard forms that automatically inherit its appearance and functionality, customizing each as appropriate.
To use visual inheritance, first design and code your master form, then build your application (Ctrl+Shift+B). Next, select Project > Add Inherited Form from the menu. Enter a name, click on Open, and choose the form you wish to inherit from. Then, further customize this form to meet your needs.
It’s worth noting that any changes you make here will not alter your original form; rather, they will just override those original inherited settings from your master form.
Secrets of Working with the System Tray
Working with the Windows system tray was never the easiest of tasks. Officially called the “status notification area,” it always involved a bundle of API calls and a little too much effort than it actually deserved. In .NET, however, it’s all about knowing which controls to use.
The heart of the whole process is the NotifyIcon component. Found in the toolbox, you’ll need to drag-and-drop this little beast straight onto your form or component. Then you need to get editing those properties: Change the Icon property to the icon you wish to use and Text to the name you wish to appear as a tool tip.
Try running your form or component as it stands so far: exactly zero lines of code later and your application can already display an icon in the system tray. But I’m guessing you want to do just a little more than that.
Most applications display a menu when the user selects the icon. For this, you need to add another toolbox component: the ContextMenu. If you’ve dropped this straight onto a form, you’ll be able to edit it just like a regular menu: add separators, write code to respond to the Click events of the individual menu items, the works. Then, change the ContextMenu property of the NotifyIcon component to point to your new menu. Next, run your application and click your icon in the system tray—result achieved!
If, on the other hand, you simply want to run a little code or display a form when your icon is clicked, check out the useful events supplied by the NotifyIcon property. You have Click, DoubleClick, MouseDown, MouseMove, and MouseUp. Simply use the code window to select one of these, then start writing your code.
And that’s it. Two controls, a couple of properties, and a handful of events are all you need to know to master the system tray.
Caption: Is that a banana in my system tray?
Best of All Worlds: Creating an Ultra-Thin Client
Talk to any modern developer about a new system you require and they’ll instantly start talking about Web-based applications. Why? There’s a very simple reason. Because ‘fat’ Windows programs are just too difficult to maintain.
Who has which version? How can you ensure all your employees start using the new system at the new time? There were workarounds… but why bother, when you can simply create a Web application?
The problem is, ‘thin’ Web applications are inflexible. They don’t give you full control. Your typical Web page can’t send something to the user’s printer, nor save files to a special area on the hard drive. They’re often slow or unavailable.
In brief, Windows programs are much better in terms of control, but worse in terms of maintainability. Web applications are great in terms of maintainability, but terrible in terms of control.
But what if you could solve this problem by automatically updating your Windows applications when opened? You can, by using reflection in .NET, a new technique allowing your code to ‘see’ other code—a sort of more-advanced late binding.
Here’s how it works: First, you create your application and put the resulting assembly (.EXE or .DLL) on the Internet or an Intranet. Next, you create a small ‘loader’ application for your users. This application then uses reflection to load your assembly from the Internet and manipulate it—perhaps displaying a form from within it.
It may sound complicated, but there are really just a couple of lines of code you’ll need to use. And here they are:
' Load assembly Dim MyAssembly As System.Reflection.Assembly = _ System.Reflection.Assembly.LoadFrom( _ "http://address/app.exe") ' Create instance of the form and show it Dim MyForm As Form = MyAssembly.CreateInstance( _ "app.Form1") MyForm.Show()
Here, the code loads the assembly from a Web address, creates a new instance of the ‘Form1’ class within the assembly, and then shows that form.
So, you may create your ‘loader’ application, then put code similar to the above behind a button, or the form’s Load event. This will download the latest version of you application from the Net, ready for you to display a form within it (for example).
Also, .NET is pretty clever. If the application you’ve ‘loaded’ references an external assembly, it will go back to your Web server to check for it. That means, if you’re feeling exceptionally smart, you might just want to split your one large application out into multiple parts. For example, in this newly downloaded application, you may refer to another assembly and display a form from within that, too. When the local machine spots this code, .NET will go back to the Web server, attempt to load that assembly, and then continue with your code.
This stops any large delays in downloading your main application, as your application is now split into many smaller ‘parts,’ all of which can work together without problem.
If you’re not too concerned with speed, however, just stick with the basics: creating a loader to download the latest version of your main application from the Net. Whenever you want clients to use a new version, simply replace your existing online assemblies—and Bob’s your Uncle.
But, as ever, there’s something you need to watch out for. It’s security. By default, the .NET Framework only partially trusts applications downloaded from the Internet and hence restricts exactly what they can do on your machine.
To sort this situation, from the Control Panel, choose Administrative Tools > Microsoft .NET Framework Wizards. Double-click the ‘Trust an Assembly’ option, specify your assembly Internet address, and grant it full permissions. There are other workarounds, too, such as adding the site your assembly is hosted on to the list of Internet Explorer ‘Trusted Sites,’ and then using the ‘Adjust .NET Security’ wizard to grant all trusted sites with full permissions—but they’re all for another day. Look up ‘code access security’ in the Help Index for more information.
Well, that’s how to automatically update your Windows programs and have the best of both worlds: complete control and no maintenance worries.
Enter stage left: return of the fat client. Hurrah and huzzah!
Coming up in the next article, part one of ASP.NET Secrets:
- Displaying Web Warning Messages: Technique 1
- Displaying Web Warning Messages: Technique 2
- Unveiled: How to Create a Default ‘Enter’ Button!
- Wonders of the Little-Known SmartNavigation Property
- The Secret Behind User Controls
See you then!
About the Author
Karl Moore is a technology author living in Yorkshire, England. He runs his own consultancy group, White Cliff Computing Ltd, and is author of two best-selling books exposing the secrets behind Visual Basic .NET. When he’s not writing for magazines, speaking at conferences, or making embarrassing mistakes on live radio, Karl enjoys a complete lack of a social life. You can visit Karl on the Web at www.karlmoore.com.
# # #