1. Architecture of WPF
This topic provides guidance on Windows Presentation Foundation (WPF) class hierarchies, covering most of the main subsystems of WPF and describing how they interact. This topic also describes in detail some of the choices made by the WPF architect.
System. Object
The main programming model of WPF is made public by hosting code. In the early stages of WPF design, there was a lot of debate about how to define managed and unmanaged components of the system. CLR provides a series of functions to make development more efficient and reliable (including memory management, error processing, and general-purpose type systems), but this requires a price.
Describes the main components of WPF. The red part of the graph (PresentationFramework, PresentationCore, and milcore) is the main code part of WPF. Only one of these components is an unmanaged component-milcore. Milcore is written in unmanaged code to achieve close integration with DirectX. All displays in WPF are completed by the DirectX engine, which enables efficient hardware and software presentation. WPF also requires precise control over Memory and execution. The composite engine in milcore is greatly affected by performance, and many advantages of CLR need to be abandoned to improve performance.
Later in this topic, we will discuss communication between managed and unmanaged parts of WPF. The following describes the rest of the managed programming model.
System. Threading. DispatcherObject
Most objects in WPF are derived from DispatcherObject, which provides the basic structure for processing concurrency and threads. WPF is a message system implemented by a scheduler. The method is similar to the common Win32 message pump. In fact, the WPF scheduler uses the User32 message to execute cross-thread calls.
To discuss concurrency in WPF, we must first understand two core concepts: scheduling program and thread Association.
In the design phase of WPF, the target tends to be executed by a single thread, but this is not an "associated" model with the thread. When a component uses the identity of the execution thread to store a certain type of state, thread Association will occur. The most common form is to use local thread storage (TLS) to store the state. Each logical thread required to be executed by thread Association is only owned by one physical thread in the operating system, which occupies a large amount of memory. Finally, the thread processing model of WPF maintains synchronization with the existing User32 thread processing model executed by a single thread associated with the thread. The main reason is interoperability-systems like OLE 2.0, clipboard, and Internet Explorer all require a single thread Association (STA) for execution.
Assume that you have an object with a STA thread, you need to communicate between threads and verify that you are on the correct thread. This is the role of the scheduler. A scheduler is a basic message scheduling system with multiple queues sorted by priority. Message examples include the original input notification (move the mouse), frame function (layout), or user command (execute this method ). Derived from DispatcherObject, you can create a CLR object with the STA action and get a pointer to the scheduler at creation.
System. Windows. DependencyObject
One of the main architecture principles used to generate WPF is the preferred attribute rather than the method or event. Attributes are declarative, making it easier to specify intent rather than action. It also supports model-driven or data-driven systems to Display User Interface content. The expected result of this idea is to create more attributes that you can bind to better control the behavior of the application.
To get more information from an Attribute-driven system, an attribute system with richer content than CLR is required. A simple example of this richness is the change notification. To implement bidirectional binding, You need to bind a change notification to both parties. To associate behavior with attribute values, you must be notified when the attribute values are changed. Microsoft. NET Framework has an INotifyPropertyChange interface that allows an object to publish a change notification (however, this is optional ).
WPF provides a rich property system derived from the DependencyObject type. The property system is actually a "dependency" property system because it tracks the dependency between attribute expressions and automatically re-verifies the attribute value when the dependency changes. For example, if you have an inherited attribute (such as FontSize), the system is automatically updated when the parent attribute of the element that inherits the value is changed.
The basis of the WPF property system is the concept of property expressions. In the first version of WPF, the attribute expression system is disabled, and expressions are provided as part of the framework. The expression causes the attribute system not to have hard-coded data binding, style adjustment or inheritance. Instead, these functions are provided by the layers behind the framework.
The attribute system also provides sparse storage of attribute values. Because an object can have dozens of attributes (if less than attributes), and most of the values are in its default state (inherited, set by style, etc ), therefore, not every instance of an object must have the full weight of each attribute defined on the object.
The last new feature of the property system is the concept of additional properties. WPF elements are generated based on the principles of combination and Component reuse. Some contained elements (such as Grid layout elements) usually need other data on the child element to control its behavior (such as row/column information ). Any object can provide attribute definitions for any other object, rather than associating all these attributes with each element. This is similar to the "expando" function in JavaScript.
System. Windows. Media. Visual
After defining a system, the next step is to draw pixels to the screen. The Visual class is used to generate a tree of Visual objects. Each object can selectively contain metadata about drawing commands and how to present these commands (editing, transformation, etc. The Visual design is extremely lightweight and flexible, so most of the functions are not open to the API and are highly dependent on protected callback functions.
Visual is actually the entry point to the WPF combination system. Visual is the connection point between the following two subsystems: hosted API and unmanaged milcore.
WPF displays data by traversing an unmanaged data structure managed by milcore. These structures (called composite nodes) represent the hierarchical display tree, where each node has a rendering command. You can only access this tree through the message passing Protocol (as shown on the right ).
When you program WPF, you will create Visual elements and derived types that communicate internally with the composite tree through this messaging protocol. In WPF, you can create one or more composite nodes without creating a composite node for each Visual.
Pay attention to a very important architectural detail-the entire tree of the visual object and the drawing command must be cached. In terms of graphics, WPF uses a retained rendering system. This allows the system to repaint at a high-refresh rate without the combined system blocking callback to user code. This helps prevent applications from responding.
Another important detail that is not very noticeable in the graph is how the system actually performs the combination.
In User32 and GDI, the system works on an instant mode editing system. When a component needs to be rendered, the system creates a cutting boundary that does not allow the component to touch pixels outside the boundary. Then, the component is required to draw pixels in the box. This system works well on systems with limited memory, because when some content changes, you only need to deal with the affected components-there will be no two components working on a pixel color change.
WPF uses the Paster algorithm to draw a model. This means that each component is not edited, but presented from the back to the front of the displayed content. This allows each component to be drawn on the display content of the previous component. The advantage of this model is that you can generate partially transparent complex shapes. Compared with today's modern graphics hardware, this model is relatively fast (except when User32/GDI is created ).
As described above, a core principle of WPF is to move to a more declarative and "Attribute-centric" programming model. In a visualization system, this is manifested in two situations that require attention.
First, if you want to retain the pattern graphics system, it is actually moving from the imperative DrawLine/DrawLine type model to the data-oriented model new Line ()/new Line (). With this data-driven rendering movement, you can perform complex operations on the rendering commands expressed by attributes. The Type derived from Drawing is actually the object model used for rendering.
Second, if you evaluate an animation system, you will see that it is almost completely declarative. Developers are not required to calculate the next position or next color. You can represent an animation as a set of attributes on an animation object. As a result, these animations can represent the intent of a developer or designer (moving the button from one position to another within five seconds ), the system can determine the most effective way to complete this task.
System. Windows. UIElement
UIElement defines core subsystems, including Layout, Input, and Event.
Layout is a core concept in WPF. In many systems, there may be a set of fixed layout models (HTML supports three layout models: stream, absolute, and table), or there may be no layout model (User32 actually only supports absolute positioning ). WPF assumes that developers and designers want to have a flexible and scalable layout model, which may be driven by attribute values rather than imperative logic. At the UIElement level, a two-phase model with the Measure and Arrange processing procedures is introduced as the basic layout protocol.
Measure allows the component to determine the size to be used. This phase is independent of Arrange, because in many cases, the parent element requires the child element to measure several times to determine its optimal position and size. The fact that the parent element requires the child element to measure is another key principle of WPF-content size. All controls in WPF support the ability to adjust the original content size. This makes localization easier and allows the Dynamic Layout of elements during the hour. The Arrange stage allows the parent element to locate and determine the final size of each child element.
It usually takes a lot of time to discuss the output end of WPF (Visual and related objects ). However