Avalon has a vast object model consisting of visual components based on a strong chain of inheritance. We learned about the first class, Visual, in this chain of inheritance in the first part of this series. This part aims at covering the next three major classes in the chain and the role each plays.
UIElement
The first class for developers to understand is the UIElement class. The remarks in the UIElement documentation perfectly capture it's purpose and I can't think of any better way to say it, so I'm just going to quote it here:
UIElement adds to the base visual class "LIFE" - Layout, Input, Focus, and Eventing. UIElement can be considered roughly equivalent to an HWND in Win32, or an Element in Trident. UIElements can render (because they derive from Visual), visually size and position their children, respond to user input (including control of where input is getting sent to), and raise events that traverse the physical tree. UIElement is the most functional type in the Windows Presentation Core.
One thing the remarks don't point out is that UIElement specifically subclasses RetainedVisual which, if you recall from my coverage of Visuals in part one, means that any UIElement you ever create will inherit RetainedVisual's rendering behavior.
Now, it is here at the UIElement class where we actually start to see behavior being added to the Avalon inheritance heirarchy that specifically has to do with user interaction. This input behavior comes through the implementation one interface in specific: IInputElement. IInputElement is a rather large interface consisting of several events and methods that have to do with handling the usual range of keyboard and mouse input as well as introducing a rather complex event routing architecture1. UIElement also provides an implementation of the ICommandTarget interface which essentilly appears to be the Avalon equivalent of OLE's IOleCommandTarget, albeit a much richer definition thereof.
FrameworkElement
The second class for developers to understand is the FrameworkElement class. FrameworkElement derives from UIElement and extends it with implementations of the following interfaces:
-
ILogicalTreeNode - Provides support for basic navigation of the visual tree akin to the DOM for XML as well, but
no where near as rich. Only simple parent/child navigation is supported.
-
ILoaded - Provides a mechanism for “bulk setup” of framework elements. This is essentially used during component initialization so that changes to the control do not result in unecessary event notifications or resource updates since the control is not yet loaded. Once you call EndLoad, all changes are propagated by the implementation to it's appearance. It also exposes an event called Loaded and a property called IsLoaded.
-
-
IDragDrop - Provides support for everybody's favorite feature, dragging and dropping. It simply appears to be a cleaner implementation than that of System.Windows.Forms.
Control's drag-drop events.
Control
The final class of importance I'm going to touch on is Control. This is the class that most of the built in Avalon controls derive from. It derives from FrameworkElement and adds some additional support for features such as:
- Context menus
- Double click notification
- Tooltips
- Font control
- Text rendering/alignment control
Back to Main Article
1 I will discuss the event routing architecture in more depth in a future article in the series.