WPF uses a multilayered architecture. At the top,
your application interacts with a high-level set of services that are
completely written in managed C# code. The actual work of translating
.NET objects into Direct3D textures and triangles happens behind the
scenes, using a lower-level unmanaged component called milcore.dll.
milcore.dll is implemented in unmanaged code because it needs tight
integration with Direct3D and because it's extremely
performance-sensitive.
Figure 1 shows the layers at work in a WPF application.
Figure 1-2 includes these key components:
PresentationFramework.dll.
This holds the top-level WPF types, including those that represent
windows, panels, and other types of controls. It also implements
higher-level programming abstractions such as styles. Most of the
classes you'll use directly come from this assembly.
PresentationCore.dll.
This holds base types, such as UIElement and Visual, from which all
shapes and controls derive. If you don't need the full window and
control abstraction layer, you can drop down to this level and still
take advantage of WPF's rendering engine.
WindowsBase.dll.
This holds even more basic ingredients that have the potential to be
reused outside of WPF, such as DispatcherObject and DependencyObject,
which introduces the plumbing for dependency properties .
milcore.dll.
This is the core of the WPF rendering system and the foundation of the
Media Integration Layer (MIL). Its composition engine translates visual
elements into the triangle and textures that Direct3D expects. Although
milcore.dll is considered part of WPF, it's also an essential system
component for Windows Vista and Windows 7. In fact, the Desktop Window
Manager (DWM) uses milcore.dll to render the desktop.
NOTE
milcore.dll is sometimes
referred to as the engine for "managed graphics." Much as the common
language runtime (CLR) manages the lifetime of a .NET application,
milcore.dll manages the display state. And just as the CLR saves you
from worrying about releasing objects and reclaiming memory, milcore.dll
saves you from thinking about invalidating and repainting a window. You
simply create the objects with the content you want to show, and
milcore.dll paints the appropriate portions of the window as it is
dragged around, covered and uncovered, minimized and restored, and so
on.
WindowsCodecs.dll. This is a low-level API that provides imaging support (for example, processing, displaying, and scaling bitmaps and JPEGs).
Direct3D. This is the low-level API through which all the graphics in a WPF application are rendered.
User32.
This is used to determine what program gets what real estate. As a
result, it's still involved in WPF, but it plays no part in rendering
common controls.
The most important fact that you should realize is Direct3D renders all
the drawing in WPF. It doesn't matter whether you have a modest video
card or a much more powerful one, whether you're using basic controls or
drawing more complex content, or whether you're running your
application on Windows XP, Windows Vista, or Windows 7. Even
two-dimensional shapes and ordinary text are transformed into triangles
and passed through the 3-D pipeline. There is no fallback to GDI+ or
User32.
1. The Class Hierarchy
Figure 2
shows a basic overview with some of the key branches of the class
hierarchy.
The following sections
describe the core classes in this diagram. Many of these classes lead to
whole branches of elements (such as shapes, panels, and controls).
NOTE
The core WPF namespaces
begin with System.Windows (for example, System.Windows,
System.Windows.Controls, and System.Windows.Media). The sole exception
is namespaces that begin with System.Windows.Forms, which are part of
the Windows Forms toolkit.
1.1. System.Threading.DispatcherObject
WPF applications use the
familiar single-thread affinity (STA) model, which means the entire user
interface is owned by a single thread. It's not safe to interact with
user interface elements from another thread. To facilitate this model,
each WPF application is governed by a dispatcher
that coordinates messages (which result from keyboard input, mouse
movements, and framework processes such as layout). By deriving from
DispatcherObject, every element in your user interface can verify
whether code is running on the correct thread and access the dispatcher
to marshal code to the user interface thread.
1.2. System.Windows.DependencyObject
In WPF, the central
way of interacting with onscreen elements is through properties. Early
on in the design cycle, the WPF architects decided to create a more
powerful property model that baked in features such as change
notification, inherited default values, and more economical property
storage. The ultimate result is the dependency property feature. By deriving from DependencyObject, WPF classes get support for dependency properties.
1.3. System.Windows.Media.Visual
Every element that appears
in a WPF window is, at heart, a Visual. You can think of the Visual
class as a single drawing object that encapsulates drawing instructions,
additional details about how the drawing should be performed (such as
clipping, opacity, and transformation settings), and basic functionality
(such as hit testing). The Visual class also provides the link between
the managed WPF libraries and the milcore.dll that renders your display.
Any class that derives from Visual has the ability to be displayed on a
window. If you prefer to create your user interface using a lightweight
API that doesn't have the higher-level framework features of WPF, you
can program directly with Visual objects.
1.4. System.Windows.UIElement
UIElement adds support for WPF essentials such as layout, input, focus, and events (which the WPF team refers to by the acronym LIFE). For example, it's here that the two-step measure and arrange layout process is defined,.
It's also here that raw mouse clicks and key presses are transformed to
more useful events such as MouseEnter. As with properties, WPF
implements an enhanced event-passing system called routed events.
1.5. System.Windows.FrameworkElement
FrameworkElement is the final
stop in the core WPF inheritance tree. It implements some of the members
that are merely defined by UIElement. For example, UIElement sets the
foundation for the WPF layout system, but FrameworkElement includes the
key properties (such as HorizontalAlignment and Margin) that support it.
UIElement also adds support for data binding, animation, and styles,
all of which are core features.
1.6. System.Windows.Shapes.Shape
Basic shapes classes, such
as Rectangle, Polygon, Ellipse, Line, and Path, derive from this class.
These shapes can be used alongside more traditional Windows widgets
such as buttons and text boxes.
1.7. System.Windows.Controls.Control
A control
is an element that can interact with the user. It obviously includes
classes such as TextBox, Button, and ListBox. The Control class adds
additional properties for setting the font and the foreground and
background colors. But the most interesting detail it provides is
template support, which allows you to replace the standard appearance of
a control with your own stylish drawing.
NOTE
In Windows Forms programming, every visual item in a form is referred to as a control. In WPF, this isn't the case. Visual items are called elements,
and only some elements are actually controls (those that can receive
focus and interact with the user). To make this system even more
confusing, many elements are defined in the System.Windows.Controls
namespace, even though they don't derive from
System.Windows.Controls.Control and aren't considered controls. One
example is the Panel class.
1.8. System.Windows.Controls.ContentControl
This is the base class for
all controls that have a single piece of content. This includes
everything from the humble Label to the Window. The most impressive part
of this model
is the fact that this single piece of content can be anything from an
ordinary string to a layout panel with a combination of other shapes and
controls.
1.9. System.Windows.Controls.ItemsControl
This is the base class for
all controls that show a collection of items, such as the ListBox and
TreeView. List controls are remarkably flexible—for example, using the
features that are built into the ItemsControl class, you can transform
the lowly ListBox into a list of radio buttons, a list of check boxes, a
tiled display of images, or a combination of completely different
elements that you've chosen. In fact, in WPF, menus, toolbars, and
status bars are actually specialized lists, and the classes that
implement them all derive from ItemsControl.
1.10. System.Windows.Controls.Panel
This is the base class for
all layout containers—elements that can contain one or more children and
arrange them according to specific layout rules. These containers are
the foundation of the WPF layout system, and using them is the key to
arranging your content in the most attractive, flexible way possible.