Overview


One of the big features of WPF is that work can be easily separated between designers and developers. The outcome from the designer’s work can directly be used by the developer. To make this possible, you have to understand XAML. The first topic of this chapter gives you an overview of WPF, enough information to understand the principles of XAML, and information on how designers and developers can cooperate. WPF consists of several assemblies containing thousands of classes. So that you can navigate within this vast number of classes and find what you need, the overview explains the class hierarchy and namespaces in WPF.

XAML

XML for Applications Markup Language (XAML) is a XML syntax used to define the hierarchical structure of the user interface. In the following line, you can see the declaration of a button named button1 with the content Click Me! The <Button> element specifies the use of the Button class:

  <Button Name="button1">Click Me!</Button> 

Tip 

There’s always a .NET class behind a XAML element. With attributes and child elements, you set the value of properties and define handler methods for events.

For testing simple XAML code you can start the utility XAMLPad.exe (see Figure 31-1) and enter the XAML code in the edit field. You can write the <Button> element within the <Page> and <Grid> elements that are already prepared from XAMLPad. With XAMLPad you can see of the XAML outcome immediately.

image from book
Figure 31-1

XAML code can be interpreted by the WPF runtime, but it can also be compiled to BAML (Binary Application Markup Language) which is done by default by Visual Studio WPF projects. BAML is added as a resource to the executable.

Instead of writing XAML, you can also create a button with C# code. You can create a normal C# console application, add references to the assemblies WindowsBase, PresentationCore, and PresentationFramework, and write the following code. In the Main() method a Window object from the namespace System.Windows is created, and the property Title is set. Then a Button object from the namespace System.Windows.Controls is created, the Content is set, and the Content of the window is set to the button. The Run() method of the Application class is responsible for processing Windows messages:

  using System; using System.Windows; using System.Windows.Controls; namespace Wrox.ProCSharp.WPF {    class m    {       [STAThread]       static void Main()       {          Window mainWindow = new Window();          mainWindow.Title = "WPF Application";          Button button1 = new Button();          button1.Content = "Click Me!";          mainWindow.Content = button1;          Application app = new Application();          app.Run(mainWindow);       }    } } 

Tip 

The Application class can also be defined by using XAML. With a Visual Studio WPF project open the file App.xaml that includes the properties and StartupUri of the Application class.

Running the application, you get a Window containing the button as shown in Figure 31-2.

image from book
Figure 31-2

As you can see, programming WPF is very similar to Windows Forms programming - with the small difference that the Button has a Content instead of a Text property. However, compared to creating the UI forms with code, XAML has some great advantages. With XAML the designer and developer can cooperate a lot better. The designer can work on the XAML code and design a stylish UI, while the developer adds functionality from the code behind using C#. It’s a lot easier to separate the UI from the functionality by using XAML.

You can directly interact with the elements that are defined with XAML from the C# code using code behind and XAML. You just have to define a name for the element and use the same name as a variable to change properties and invoke methods.

The button has a Content property instead of a Text property because the button can show anything. You can add text to the content, but also a graphic, a list box, a video–whatever you can think of.

Properties as Attributes

Before working with XAML, you need to know important characteristics of the XAML syntax. You can use XML attributes to specify the properties of classes. The example shows the setting of the Content and Background properties of the Button class:

  <Button Content="Click Me!" Background="LightGreen" /> 

Properties as Elements

Instead of using XML attributes, the properties can also be specified as child elements. The value for the content can directly set by specifying the child elements of the Button element. For all other properties of the Button, the name of the child element is defined by the name of the outer element, followed by the property name:

  <Button>   <Button.Background>     LightGreen   </Button.Background>   Click Me! </Button> 

In the previous example, it is not necessary to use child elements; by using XML attributes, the same result was achieved. However, using attributes is no longer possible if the value is more complex than a string. For example, the background can not only be set to a simple color but also to a brush; for example, a linear gradient brush:

 <Button>    <Button.Background>     <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">       <GradientStop Color="Yellow" Offset="0.0" />       <GradientStop Color="Orange" Offset="0.25" />       <GradientStop Color="Red" Offset="0.75" />       <GradientStop Color="Violet" Offset="1.0" />     </LinearGradientBrush>    </Button.Background>    Click Me! </Button>

Dependency Property

When programming WPF, you often come across the term dependency property. WPF elements are classes with methods, properties, and events. Nearly every property of a WPF element is a dependency property. What does this mean? A dependency property can be dependent on other inputs; for example, themes and user preferences. Dependency properties are used with data binding, animation, resources, and styles.

From the programmatic viewpoint, a dependency property can be read and written not only by invoking the strongly typed property but also by methods passing a dependency property object.

Only a class that derives from the base class DependencyObject can include dependency properties. The following class, MyDependencyObject, defines the dependency property SomeState. SomeStateProperty is a static field of type DependencyProperty that backs the dependency property. The dependency property is registered with the WPF dependency property system using the Register() method. The Register() method gets the name of the dependency property, the type of the dependency property, and the owner type. You can set the value of the dependency property by using the SetValue() method of the DependencyObject base class, and get the value by using the method GetValue(). Dependency properties usually have a strongly typed access as well. Instead of using the methods of the DependencyObject base class, the class MyDependencyObject includes the property SomeState, which invokes the methods SetValue() and GetValue() from the implementation of the set and get accessors.

  public class MyDependencyObject : DependencyObject {    public static readonly DependencyProperty SomeStateProperty =       DependencyProperty.Register("SomeState", typeof(String),          typeof(MyDependencyObject));    public string SomeState    {       get { return (string)this.GetValue(SomeStateProperty); }       set { this.SetValue(SomeStateProperty, value); }    } } 

Tip 

With WPF the class DependencyObject is very high in the hierarchy. Every WPF element is derived from this base class.

Attached Property

A WPF element can also get features from the parent element. For example, if the Button element is located inside a Canvas element, the button has Top and Left properties that are prefixed with the parent element’s name. Such a property is known as attached property:

  <Canvas>   <Button Canvas.Top="30" Canvas.Left="40">     Click Me!   </Button> </Canvas> 

Writing the same functionality from the code behind is a little bit different because the Button class doesn’t have a Canvas.Top and Canvas.Left property, even if it is contained within the Canvas class.

There’s a naming pattern for setting attached properties that is common with all classes. The class supporting attached properties has static methods with the names Set<Property> and Get<Property>, where the first parameter is the object that the property value is applied to. The Canvas class defines the static methods SetLeft() and SetTop() to get the same result as in the XAML code shown earlier.

 [STAThread] static void Main() {    Window mainWindow = new Window();    Canvas canvas = new Canvas();    mainWindow.Content = canvas;     Button button1 = new Button();    canvas.Children.Add(button1);     button1.Content = "Click Me!";    Canvas.SetLeft(button1, 40);    Canvas.SetTop(button1, 30);    Application app = new Application();    app.Run(mainWindow); }

Tip 

An attached property can be implemented as a dependency object. The method DependencyProperty .RegisterAttached() registers an attached property.

Markup Extensions

When setting values for elements you can set the value directly, but sometimes markup extensions are very helpful. Markup extensions consist of curly brackets followed by a string token that defines the type of the markup extension. Here is an example of a StaticResource markup extension:

  <Button Name="button1" Style="{StaticResource key}" Content="Click Me" /> 

Instead of using the markup extension, you can write the same thing using child elements:

  <Button Name="button1">   <Button.Style>     <StaticResource ResourceKey="key" />   </Button.Style>   Click Me! </Button> 

Markup extensions are mainly used for accessing resources and for data binding. Both of these topics are discussed later in this chapter.

Cooperation of Designers and Developers

The design of Windows applications very often is done directly by the developer. This is especially true if the application was built just for inhouse use. If someone with UI design skills was hired to design the UI, usually the developer is given a JPG file of the designer’s vision of how the UI should look like.

The developer then has the problem of trying to match the designer’s plans. Even simple changes by the designer, such as a different look for list boxes or buttons, can lead to a huge investment using owner-drawn controls. As a result, the UI done by the developer looks very different from the UI that was originally designed.

With WPF this changes. The designer and developer can work on the same XAML code. The designer can use a tool such as Expression Interactive Designer (EID), while the developer makes use of Visual Studio 2005. Both can work using the same project files. In the typical progression of this cooperative process, the designer starts a project with EID, using the same project files as in Visual Studio. Then the developer takes over to work on the code behind, while at the same time the designer enhances the UI. As the developer enhances the functionality, the designer can also add new UI features that take advantage of the functionality provided by the developer.

Of course, it is also possible to start the application with Visual Studio and enhance the UI later with EID. You just have be careful not to do a UI as you used to do with Windows Forms, as this doesn’t take the full advantage of WPF.

Figure 31-3 shows the Expression Interactive Designer that was created by using WPF. In this application, zooming is available for both the workspace and the document because WPF is based on vector graphics.

image from book
Figure 31-3

Tip 

Comparing EID to Visual Studio extensions, the EID has great features for defining styles, creating animations, using graphics, and the like. To work cooperatively, the EID can use code-behind classes done by the developer, and the designer can specify the data binding from the WPF elements to the .NET classes. The designer can also test the complete application by starting it from EID. Because EID uses the same MS-Build files as Visual Studio does, the code-behind C# code is compiled to run the application.

Class Hierarchy

WPF consists of thousands of classes with a deep hierarchy. To help in understanding the relationship among the classes, Figure 31-4 shows some of the WPF classes in a class diagram. Some classes and their functionality are described in the following table.

Open table as spreadsheet

Class

Description

DispatcherObject

DispatcherObject is an abstract base class for classes that are bound to one thread. WPF requires similar to Windows Forms that methods and properties only to be invoked from the creator thread. Classes that are derived from DispatcherObject have an associated Dispatcher object that can be used to switch the thread.

Application

In a WPF application, one instance of the Application class is created. This class implements a Singleton pattern for access to the windows of the application, resources, and properties.

DependencyObject

DependencyObject is the base class for all classes that support dependency properties. Dependency properties were discussed earlier.

Visual

The base class for all visual elements is Visual. This class includes features for hit testing and transformation.

UIElement

The abstract base class for all WPF elements that need basic presentation features is UIElement. This class provides tunneling and bubbling events for mouse moves, drag and drop, and key clicks; exposes virtual methods for rendering that can be overridden by derived classes; and provides methods for layout. You already know that WPF no longer uses Window handles. You can consider this class equivalent to a Windows handle.

FrameworkElement

FrameworkElement is derived from the base class UIElement and implements the default behavior of the methods defined by the base class.

Shape

Shape is the base class for all shape elements; for example, Line, Ellipse, Polygon, Rectangle.

Control

Control derives from FrameworkElement and is the base class for all user-interactive elements.

Panel

The class Panel derives from FrameworkElement and is the abstract base class for all panels. This class has a Children property for all UI elements within the panel and defines methods for arranging the child controls. Classes that are derived from Panel define different behavior for how the children are organized; for example, WrapPanel, StackPanel, Canvas, Grid.

ContentControl

ContentControl is the base class for all controls that have a single content (for example: Label, Button). The default style of a content control may be limited, but it is possible to change the look by using templates.

image from book
Figure 31-4

As you can see, WPF classes have a really deep hierarchy. In this chapter, you will see classes of the core functionality, but it is not possible to cover all the features of WPF with one chapter.

Namespaces

Classes from Windows Forms and WPF can easily be confused. The Windows Forms classes are located in the namespace System.Windows.Forms, while the WPF classes are located inside the namespace System .Windows and subnamespaces thereof, with the exception of System.Windows.Forms. The Button class for Windows Forms has the full name System.Windows.Forms.Button, the Button class for WPF has the full name System.Windows.Controls.Button.

Tip 

Windows Forms is covered in Chapters 28 and 29.

Namespaces and their functionality with WPF are described in the following table.

Open table as spreadsheet

Namespace

Description

System.Windows

This is the core namespace of WPF. Here you can find core classes from WPF such as the Application class; classes for dependency objects, DependencyObject and DependencyProperty; and the base class for all WPF elements, FrameworkElement.

System.Windows.Annotations

The classes from this namespace are used for user-created annotations and notes on application data that are stored separately from the document. The namespace System.Windows .Annotations.Storage contains classes for storing annotations.

System.Windows.Automation

The namespace System.Windows.Automation can be used for automation of WPF applications. Several subnamespaces are available. System.Windows.Automation.Peers exposes WPF elements to automation; for example, ButtonAutomationPeer and CheckBoxAutomationPeer. The namespace System.Windows .Automation.Provider is needed if you create a custom automation provider.

System.Windows.Controls

This is the namespace where you can find all the WPF controls, such as Button, Border, Canvas, ComboBox, Expander, Slider, ToolTip, TreeView, and the like. In the namespace System .Windows.Controls.Primitives you can find classes to be used within complex controls; for example, Popup, ScrollBar, StatusBar, TabPanel, and so on.

System.Windows.Converters

The namespace System.Windows.Converters contains classes for data conversion. Don’t expect to find all converter classes in this namespace. Core converter classes are defined in the namespace System.Windows.

System.Windows.Data

The namespace System.Windows.Data is used by WPF data binding. An important class in this namespace is the Binding class, which is used to define the binding between a WPF target element and a CLR source.

System.Windows.Documents

When working with documents, you can find many helpful classes in this namespace. FixedDocument and FlowDocument are content elements that can contain other elements from this namespace. With classes from the namespace System.Windows .Documents.Serialization you can write documents to disk.

System.Windows.Ink

The Windows Tablet PC and Ultra Mobile PCs are being used more and more. With these PCs, ink can be used for user input. The namespace System.Windows.Ink contains classes to deal with ink input.

System.Windows.Input

The namespace System.Windows.Input contains several classes for command handling, keyboard inputs, working with a stylus, and so on.

System.Windows.Interop

For integration with Win32 and WPF, you can find classes in the namespace System.Windows.Interop.

System.Windows.Markup

Helper classes for XAML markup code are located in this namespace.

System.Windows.Media

To work with images, audio, and video content, you can use classes in the System.Windows.Media namespace.

System.Windows.Navigation

This namespace contains classes for navigation between windows.

System.Windows.Resources

This namespace contains supporting classes for resources.

System.Windows.Shapes

The core classes for the UI are located in the namespace System .Windows.Shapes: Line, Ellipse, Rectangle, and the like.

System.Windows.Threading

WPF elements are similar to Windows Forms controls bound to a single thread. In the namespace System.Windows.Threading, you can find classes to deal with multiple threads; for example, the Dispatcher class belongs to this namespace.

System.Windows.Xps

XML Paper Specification (XPS) is a new document specification that is also supported by Microsoft Word. In the namespaces System.Windows.Xps, System.Windows.Xps.Packaging, and System.Windows.Xps.Serialization, you can find classes to create and stream XPS documents.




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net