The four components that handle rendering for WPF are:Visual SystemMessage Transport SystemComposition SystemVisual SystemThe Visual System is responsible for parsing XAML and creating appropriate managed objects for representation of this UI. Once these managed objects are created, these are handed over to the Message Transport System.Message Transport SystemThe Message Transport System receives managed objects representing the UI from the Visual System and passes them over to the Composition System using Remoting. Using Remoting, data structures are passed across boundaries to the Composition System.Composition SystemThe Composition System is actually responsible for communicating with the underlying hardware in order to render the UI. The Composition System passes on information on rendering the UI to the GPU, if available. This keeps the CPU free for other operations, thus improving user experience.
WPF uses vector graphics, which means that all rendering is scalable. All graphics run at same quality for different screen resolutions.
The WPF property system comprises of the following:Change Notification: This is related to automatically refreshing the UI when data bound to the UI changesStorage: This is related to the way in which UI objects and information related to them is storedExpressions: This is related to the syntax though which UI elements are bound to data or to each otherChange NotificationThere are various methods by which updates on the UI can be propagated back to the original data object and vice versa. One of the ways in which this can be implemented is using INotifyPropertyChanged interface. Another way is to use Dependency Properties. These will be discussed in detail in the coming slides.StorageAs would be discussed in the coming slides, WPF provides options for reducing the memory footprint of the application by allowing the developers to store default control properties as static shared values.ExpressionsAnything in XAML that is written between curly braces is an expression. An expression can be used for binding a UI element with a static resource or a dynamic resource. A static resource is one for which the value is fixed when the application starts and does not change during the lifetime of the application. This can be the definition of a style in an App.xaml file or something similar.A dynamic resource is one which can be changed during the lifetime of the application. This can be an object of a class, property, command etc. As shown in the image, the Command property of the Grid has been bound to the dynamic resource “MoveNextCommand”. This would be a method present in the class that acts as the datacontext of the grid. [show sample code here]Also, the style property of the grid has been bound to a static resource, which defined the style. [show sample code here]While specifying an expression for binding, it is possible to specify a Mode for the binding. Possible values are as follows:One way: GUI element is updated whenever the object to which element is bound is updatedTwo way: GUI element is updated whenever the object to which element is bound is updated. Also, object is updated whenever GUI changes.OneTime: The object to which the UI element is bound can change the value of GUI element only once. OneWayToSource: Object to which UI element is bound is updated each time the UI element changes. Not vice-versa.
The INotifyPropertyChanged interface allows synchronization of property values with the UI. This interface exposes the OnPropertyChanged event, which is implemented by all classes that inherit from this interface. This event can be fired from the property’s set method as and when required. [show sample code here]The drawback of this interface is that each time a property’s set method is called, its modified value has to be optionally compared with the original value and if the value is different, the OnPropertyChanged event needs to be called. This gets cumbersome for a class with a lot of properties.
Dependency properties can be used as an alternative to INotifiPropertyChanged interface and serve the same purpose – synchronization of UI and source. The advantage of using dependency properties is with respect to the storage of these properties. A dependency property for a class is static and hence is shared among the various instances of the class IF all the instances keep the default value for that property. If any of the instances of that class use a non-default value for the property, the internal logic of dependency properties maintain that modified value.This is achieved through hash tables. All dependency properties are stored as hashes. Thus, for a class having all instances at default value, the hash contains only one entry. As instances move from the default value, the entries in this hash increase.Dependency properties are thus beneficial for scenarios where most of the instances of the class are known to keep default values.[Show sample code for dependency properties]
Back to the presentation layer, it is often a question as to why we have invented XAML. The idea behind XAML, besides separating designing from development for windows apps, is to make interfaces somewhat portable between windows and web applications. All interfaces designed in XAML for web applications can be used with windows applications with slight changes.
Once the XAML for the page is defined, it can be parsed using two types of trees exposed by WPF: Logical treeVisual treeLogical TreeThe logical tree represents the XAML as is. This means if you have places a grid on a window and a text block and combo box inside it, the LogicalTree.GetParent method for the text block and combo box would return the grid itself. The grid is the logical parent for these elements, even though internally WPF may be creating a border inside the grid in which these controls are placed.Each element of a Logical Tree is a UIElement, but may be of any control type.
Visual TreeThe visual tree is a representation of the actual code that is generated by WPF from the XAML page. For example, if a grid contains a textblock that contains some text, the visual tree may contain grid, textblock, border, and then text. In this case, the VisualTree.GetParent method for the text box would fetch the border.Every element of a visual tree is a dependency property. The visual tree is used by WPF while routing events. This is because if a text block is clicked, there are various possibilities. Maybe the border inside the text block was clicked. Maybe the text was clicked. All events for the visual tree children of this text block would bubble up the click event to the parent.
We have seen how an individual interface can be created using XAML. Now let’s see how these interfaces can be used. WPF provides the following types of XAML interfaces:WindowNavigation WindowPageA window can be compared to a stand-alone window in any windows application. This window has its own minimize/maximize/close buttons (if enabled) and can launch/be launched from another window.A navigation window can be compared to a browser window for a web application. This window has its own mechanism for storing a next/previous history of pages visited.A page is an interface which is displayed inside a navigation window.
Once the interface is ready, the events need to be bound to various UI elements. WPF introduces the following types of events:Routed EventsCommandsAttached Events
Routed Events: As discussed before, WPF created a visual tree internally for XAML. Thus, a simple control like a text block may be composed of border, text, and various other dependency properties. In order to make sure that the click event of any of the child visual elements fires the correct text block event, routed events are used. A routed event can be of the following types: BubblingTunnelingDirectBubbling EventsBubbling events, as the name suggests, bubble up from the child control to the parent control in the visual tree hierarchy.[Show code sample]Tunneling EventsTunneling events tunnel down from the parent control to (all) child controls in the visual tree hierarchy.[Show sample code]Direct EventsDirect events are the same as the web/windows application events seen so far.Please note that for bubbling/tunneling events, if at any level, e.handled is set as true, the event is still internally bubbled/tunneled to all levels. Only the event handler is not fired once e.handled is set to true. This behavior can be changed by using UIElement.AddHandler method. This method has a boolean parameter that can be used for specifying whether event handler should be fired even if it has been handnled at a previous level.
Commands: Commands can be considered as a global repository of events that can be attached to/fired from any part of the application. Commands are created by inhering a class from the ICommand interface. [Show and discuss sample code]
Attached Events: Attached events can be used for handling events for a UI element from another UI element. This may be useful in cases where we have user controls. Consider a scenario in which a parent window calculates some value according to the values selected by the user in a user control. In this case, all selection changed events for dropdowns should be handled at the parent window level, since the calculation logic resides in that class, not in the user control. In this scenario, the parent grid can define an attached event that handles all drop-down selection changed events.[Show and explain sample code here]
IndexO RenderingO Property System O Change Notification O Storage O ExpressionsO XAML O Logical Tree O Visual TreeO BindingO NavigationO Events O Routed Events O Commands O Attached Events
Rendering Composition Visual System System RemotingObjects CPU GPUMessage Transport Screen System