So how are all these objects exposed? The key is to create an
object that exposes them globally, like a singleton. For instance, in the Word
API, there is an Application object that is the core object for references. I
like to follow a similar approach, where I group all of these sorts of objects
in an application object.
Thus, the creation of the ApplicationModel object exists,
which exposes menu items, document windows, tool windows for the left, right,
and/or bottom, and toolbars. One central object can be used to listen to each
child object's events, and make that notification known to the whole
application. For instance, below are two of the property definitions:
Listing 11
public DocumentWindowCollection DocumentWindows
{
get
{
if (_documentWindows == null)
{
_documentWindows = new DocumentWindowCollection();
AttachToDocumentWindowEvents(_documentWindows);
}
return _documentWindows;
}
}
public MenuItemCollection Menus
{
get
{
if (_menus == null)
{
_menus = new MenuItemCollection();
AttachToMenuEvents(_menus);
}
return _menus;
}
}
The attach method attaches to the collection events, which
are fired everytime an object is manipulated within the collection. The
following illustrates the broadcasting of those events; when these events fire,
they are thrown up to a parent through another set of events, which I will not
show for brevity purposes. You'll be able to see that in the code attached
though.
Listing 12
private void AttachToDocumentWindowEvents(DocumentWindowCollection
documentWindows)
{
documentWindows.ItemAdded += OnDocumentWindowAdded;
documentWindows.ItemAdding += OnDocumentWindowAdding;
documentWindows.ItemInserted += OnDocumentWindowInserted;
documentWindows.ItemInserting += OnDocumentWindowInserting;
documentWindows.ItemRemoved += OnDocumentWindowRemoved;
documentWindows.ItemRemoving += OnDocumentWindowRemoving;
}
Furthermore, the application model object can house other
properties, such as a status, as shown below. This root object is a good place
to put certain properties.
Listing 13
public string Status
{
get
{
return _status;
}
set
{
if (string.Compare(_status, value, StringComparison.CurrentCulture) != 0)
{
_status = value;
OnStatusChanged(EventArgs.Empty);
}
}
}