Synchronizing UI Elements
When designing common Windows Forms Application, it always turns out to be a bit of a hassle to synchronize different UI elements like a MenuItem and a Toolbar Item that execute (or should execute) the same code or should be activated and deactivated at the same time.
Using Commands
One Solution to this problem is to delegate the work to a command class and then attach one or more UI elements to this class. The Command Class will then be in charge of executing commands, enable, disable, hide or show the attached elements.
In a future version I will provide a command extender that can be dragged onto a form and UI elements can then be attached to it. Meanwhile you will find some code that will allow you to use those command classes in code.
Using command classes in code has advantages too. You can create your very own application model with all the commands you need in your app as you will see in the demo app.
The Command Class
The Command Class itself contains a collection of attached components, some properties that will be explained shortly and some events that are used to inform the commands containing class of any changes in the command class.
Public Properties
There are three Properties (PropagateEnabled, PropagateVisible, PropagateText) that will allow one attached component to change the command’s Enabled, Visible or Text Property which will in turn propagate those changes to all other attached components. Setting the Visible and Enabled Property directly on the command object will always result in the propagation of the property value to all attached components.
The standard behaviour of the Text property is to NOT PROPAGATE to all attached components because this could end in some „funny“ scenarios because you could also attach textboxes to the command class. On the other hand, propagating the Text can be useful if the menu item or button should display certain states and be constant over all attached components.
Dim WithEvents MyCommand as New Command
MyCommand.PropagateEnabled = True
MyCommand.Add( menuItem1 )
MyCommand.Add( toolbarItem1 )
...
'this will disable menuItem1 AND toolbaritem1
menuItem1.Enabled = False
Public Methods
The Add- and Remove-Method allow you to attach any Control or ToolStripItem to a command. Because most controls support an Enabled or Visible property, attaching textboxes, buttons and/or menu items to one command you can design highly interactive UI that could disable or hide a wide range or elements by simply setting one command property.
Calling the Clear method will remove all attached components at once.
The Execute Method will invoke the Click handler which can be intercepted in the parent class and the apropriate code can be executed for this command.
Using the Command Classes
The code includes a very simple editor application that will allow you to open, save and edit a text file. The editor’s behaviour is not programmed into the form. The project has a shared class called EditorApplication that includes all methods and commands that can be executed from the editor. It also supports some events that the editor can use to show changes.
The EditorApplicationClass
As mentioned before, all the behaviour is in this class. All methods and events are declared shared so that the class must not be instantiated but can be used immediately in the main form. The class has a child class called Commands where all available commands for this application are defined. The class also includes the event handling of each command which in return calls a method of the EditorApplication.
Public Class EditorApplication
Public Class Commands
Public Shared WithEvents OpenFile As New Command
Public Shared WithEvents SaveFile As New Command
Public Shared WithEvents CloseFile As New Command
Public Shared WithEvents NewFile As New Command
Public Shared WithEvents ChangeFont As New Command
Public Shared WithEvents SaveFileAs As New Command
Private Shared Sub ChangeFont_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ChangeFont.Click
EditorApplication.ChangeFont()
End Sub
Private Shared Sub CloseFile_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CloseFile.Click
EditorApplication.CloseFile()
End Sub
...
End Class
Public Shared Sub CloseFile()
If Not CheckFile() Then Exit Sub
CurrentFile = ""
Content = ""
IsDirty = False
IsNew = False
Commands.SaveFile.Enabled = False
Commands.SaveFileAs.Enabled = False
Commands.CloseFile.Enabled = False
End Sub
...
End Class
The EditorApplication keeps track of the current file, the current content and any status changes and raises events or changes commands accordingly.
The Editor Form
The editor form itself is very simple. You can define all UI elements by dragging them from the toolbox. In a next step you go to the Load event of the form and attach every UI elemtent to the related command object of the application class. You then hook up any EditorApplication Event you’re interested in and then you’re ready to go.
Private Sub AttachCommands()
EditorApplication.Commands.ChangeFont.Add(ChangeFontToolStripMenuItem)
EditorApplication.Commands.ChangeFont.Add(tsChangeFont)
EditorApplication.Commands.CloseFile.Add(CloseToolStripMenuItem)
EditorApplication.Commands.NewFile.Add(NewToolStripMenuItem)
EditorApplication.Commands.NewFile.Add(tsNew)
EditorApplication.Commands.OpenFile.Add(OpenToolStripMenuItem)
EditorApplication.Commands.OpenFile.Add(tsOpen)
EditorApplication.Commands.SaveFile.Add(SaveToolStripMenuItem)
EditorApplication.Commands.SaveFile.Add(tsSave)
EditorApplication.Commands.SaveFileAs.Add(SaveAsToolStripMenuItem)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AttachCommands()
AddHandler EditorApplication.FileChanged, AddressOf OnFileChanged
AddHandler EditorApplication.ContentChanged, AddressOf OnContentChanged
AddHandler EditorApplication.FontChanged, AddressOf OnContentFontChanged
AddHandler EditorApplication.StatusChanged, AddressOf OnStatusChanged
rtfText.Enabled = False
EditorApplication.Commands.SaveFile.Enabled = False
EditorApplication.Commands.SaveFileAs.Enabled = False
EditorApplication.Commands.CloseFile.Enabled = False
EditorApplication.CurrentFont = Me.rtfText.Font
End Sub
...
Private Sub OnStatusChanged(ByVal sender As Object, ByVal e As EventArgs)
Me.Text = String.Format("{0}{1}", EditorApplication.CurrentFile, IIf(EditorApplication.IsDirty, "*", ""))
If EditorApplication.CurrentFile = "" And EditorApplication.IsNew = False Then
rtfText.Enabled = False
End If
End Sub
Currently rated 4.0 by 1 people
- Currently 4/5 Stars.
- 1
- 2
- 3
- 4
- 5