JETZT ONLINE BESTELLEN
Add to Cart
XAML in a Nutshell

First Edition April 2006
ISBN 978-0-596-52673-3
302 Seiten
EUR24.50

Weitere Informationen zu diesem Buch

Inhaltsverzeichnis |


Inhaltsverzeichnis

	
Chapter 1: Introducing XAML
Inhaltsvorschau
XAML (pronounced "Zamel") stands for eXtensible Application Markup Language. It is Microsoft's new declarative language for defining application user interfaces. XAML provides an easily extensible and localizable syntax for defining user interfaces separated from application logic, similar to the object-oriented technique for developing n-tier applications with a MVC (Model-View-Controller) architecture.
XAML was created by Microsoft expressly for the purpose of interfacing with its .NET Framework on its Windows Vista (formerly codenamed "Longhorn") operating system through the WinFX (codename "Avalon") presentation subsystem runtime environment. XAML gives developers the ability to control the layout of all .NET user-interface elements such as text, buttons, graphics, and listboxes, using XML . Because XAML is XML-based, your code must be well-formed XML. Every XAML tag corresponds directly to a .NET Framework class whose properties are controlled through the use of XML attributes. For example, the <Button> tag corresponds directly to the System.Windows.Controls.Button class. XAML elements represent a Common Language Runtime (CLR) class, the runtime engine for Microsoft's .NET framework. The CLR is similar to the Java Virtual Machine (JVM), except that the JVM can only run Java language programs, while the CLR can run applications written in a number of .NET languages, such as C#, J#, and VB.NET.
Because XAML elements represent CLR objects (this book focuses on those in the Windows Presentation Foundation [WPF]), anything that can be done with XAML can also be accomplished with procedural code. There are some things, however, that can be done by manipulating the object model programmatically that are not accessible through XAML. Properties that are read-only are not exposed through XAML; only those properties that are public and have both a get and a set method are accessible to XAML developers.
Events and handlers can also be specified by XAML attributes, and the necessary code behind the handlers, codebehind
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
The Benefits of XAML
Inhaltsvorschau
XAML offers similar benefits to other markup-based application interface mechanisms such as XUL (eXtensible User-interface Language), HTML (HyperText Markup Language), and Flex. Markup-based interfaces are quick to build and easily modifiable. They require less code than traditional structured programming. For example, creating and defining the properties of a Button with XAML requires just one line of syntax, as opposed to multiple lines in C# or VB.NET:

    <Button Click="OnClickHandler" Background="Green" Content="Submit" />

The same Button object created using C# requires four lines:

    Button myBtn = new Button(  );

    myBtn.Background = Brushes.Green;

    myBtn.Text="Submit";

    myBtn.Click += new System.EventHandler(OnClickHandler);

While HTML has limited programmatic functionality and control, XAML and other new-generation declarative markup languages offer back-end scripting language support to circumvent this limitation. While XAML separates the user interface from application logic, it still provides a mechanism by which the two can easily interact. This separation offers several benefits, including easily localized user interfaces and the ability for developers to modify application logic without affecting the user interface, and vice versa.
XAML also opens up user-interface design to a wider group of developers, namely graphic designers and markup developers. Anyone with experience using HTML or other web-oriented markup languages will find XAML to be intuitive; they will be able to jump in and begin developing user interfaces in a short period of time. This alleviates the burden placed on .NET developers and allows them to focus on developing application logic, while others determine the look and feel of the user interface.
XAML is toolable, which offers third-party developers opportunities to create applications that support it. Several third-party applications already exist that offer visual environments for developing XAML. Additional products are expected as Windows Vista begins to be generally deployed.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
What XAML Is Not
Inhaltsvorschau
XAML is purely a markup language designed for describing user-interface components and arranging them on the screen. Though there are components of XAML that appear to be programmatic in nature, such as the Trigger and Transform elements, XAML is not a procedural programming language and is not designed to execute application logic.
XAML is interpreted, not compiled—though it can be compiled. Microsoft recommends that XAML be compiled by compacting it into Binary Application Markup Language (BAML) . Both XAML and BAML are interpreted by the WPF and then rendered on the screen in a manner similar to HTML. Unlike HTML, however, XAML is strongly typed. HTML defaults to ignoring tags and attributes it doesn't understand, while XAML requires that every tag and attribute be understood, including the typing of attributes. Although all attributes initially appear to be strings, don't let that fool you. The string represents an object, and because those objects must be understood by WPF, XAML is strongly typed.
Finally, XAML is not HTML. Although there are similarities in the declaration of elements, application of styles, and assignment of event handlers, XAML is an XML-based interface to the Windows Presentation Framework, while HTML is a markup language that is rendered within the context of the browser and operating system in which it is loaded. XAML is far more than a mechanism for displaying information and soliciting basic user input. It is a complete user-interface design and development markup language that reaches beyond the scope of simple HTML elements by including advanced features such as 3-D element rendering and rich vector-based drawing capabilities.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
XAML Development Resources
Inhaltsvorschau
XAML can be developed in myriad ways. XAML can be written in any text editor. For example, all the code included in this book was written in Notepad and then compiled using MSBuild.
There are much easier ways to develop a XAML user interface, however, and most of them involve a visual layout tool. There are several third-party tools, as well as tools from Microsoft that support XAML. Some are focused on only one aspect of XAML, such as development of 3-D interfaces, while others are more generally applicable. Some popular tools available as of this writing include:
Electric Rain ZAM D XAML Tool (http://www.erain.com/products/zam3d/)
A tool that supports visual development of 3-D interface elements for XAML.
Xamlon Pro and XAML Converter (http://www.xamlon.com/)
Xamlon Pro supports development of XAML user interfaces in a visual environment. XAML Converter converts other formats to XAML.
MyXAML (http://www.myxaml.com/)
An open source project dedicated to XAML development. Includes a mailing list and forums focused on discussion of XAML and the sharing of tips, tricks, and techniques.
Mobiform Aurora XAML Editor (http://www.mobiform.com/2005/XAML/xamlhome.htm)
A visual editor for XAML from Mobiform.
XamlViewer (http://weblogs.asp.net/gmilano/archive/2004/11/24/269082.aspx)
A visual editor for XAML that integrates into Visual Studio 2005.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 2: Getting Started with XAML
Inhaltsvorschau
As with most development-oriented tools, it's important to have the proper environment before you can start developing user interfaces with XAML. This chapter discusses the prerequisites necessary to define and run XAML applications and later details the basic structure of a XAML project, as well as how to compile and run that application.
This chapter assumes that you have a working knowledge of XML and are at least somewhat familiar with other user-interface markup languages, such as ASP.NET and HTML.
Although XAML is designed specifically for Windows Vista, it's also available on Windows XP and Windows Server 2003, given that certain system requirements are met. This makes it possible for developers to become familiar with XAML and the WinFX SDK before Windows Vista is officially available.
XAML can be used to develop applications on the following operating systems:
  • Windows XP SP2
  • Windows Server 2003 SP1
  • Windows Vista
On Windows XP SP2 and Windows Server 2003 SP1, you will first need to install the WinFX runtime, which contains, among other things, the Windows Presentation Foundation (Avalon). Regardless of the operating system you choose, you'll need to install the WinFX SDK. The SDK contains the libraries, build tools, and documentation necessary to begin developing user interfaces with XAML. Depending on the operating system you choose, the WinFX SDK may also have prerequisites that must be met.
If you plan on using the WinFX Extensions to Visual Studio 2005, you must install Visual Studio 2005 before installing the WinFX SDK.
A XAML application comprises two types of elements: an application element and the set elements that make up the user interface. The XAML files contain the user-interface definition for your application. The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
XAML Prerequisites
Inhaltsvorschau
Although XAML is designed specifically for Windows Vista, it's also available on Windows XP and Windows Server 2003, given that certain system requirements are met. This makes it possible for developers to become familiar with XAML and the WinFX SDK before Windows Vista is officially available.
XAML can be used to develop applications on the following operating systems:
  • Windows XP SP2
  • Windows Server 2003 SP1
  • Windows Vista
On Windows XP SP2 and Windows Server 2003 SP1, you will first need to install the WinFX runtime, which contains, among other things, the Windows Presentation Foundation (Avalon). Regardless of the operating system you choose, you'll need to install the WinFX SDK. The SDK contains the libraries, build tools, and documentation necessary to begin developing user interfaces with XAML. Depending on the operating system you choose, the WinFX SDK may also have prerequisites that must be met.
If you plan on using the WinFX Extensions to Visual Studio 2005, you must install Visual Studio 2005 before installing the WinFX SDK.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Defining XAML Applications
Inhaltsvorschau
A XAML application comprises two types of elements: an application element and the set elements that make up the user interface. The XAML files contain the user-interface definition for your application. The codebehind files will contain the application logic and the code that handles event processing. XAML does not provide a mechanism for handling events, but it can direct the runtime engine to call event handlers written in C# or VB.NET. If you're a developer, you'll code the event handlers and application logic just as you always have, but because the user-interface code is separate, you'll have to pay a bit more attention to the names of the handlers and elements you reference because you don't define them—they're declared and named in the XAML file.
You can define XAML applications completely using C# or VB.NET. The CLR classes represented by XAML are all accessible through code, and you can write applications just as you always have, if you so desire. XAML offers you the ability to completely separate the presentation layer (user interface) from the application logic, thus making it easier to split up development responsibilities and isolate UI changes from the code. Appendix H provides an example of an application declared in XAML, as well as entirely in C#.
The most common application element is of type NavigationApplication. NavigationApplication defines an application that behaves like a web application or wizard in that it consists of pages between which a user navigates using hyperlinks and forward and back buttons.
The application definition is generally declared in its own file. It requires two properties to be set, the namespace and the startup URI, which is the URI of the first page that should be loaded when the application starts. For our purposes in this chapter, the application definition file will be called
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Building XAML Applications
Inhaltsvorschau
While XAML can be used to create libraries and modules that can be shared and used to build other applications (in the same way that C# or VB.NET can be used to build DLLs or shared assemblies), it is more likely that you will use XAML to generate an application. There are two types of XAML applications: express and installed. Express applications are hosted in a web browser. Installed applications are traditional desktop applications and can be either Windows applications or console applications. The type of application generated is determined by a property value in the project file MSBuild uses to assemble the application.
MSBuild is one of the new features in Windows Vista and Visual Studio 2005. With the release of Visual Studio 2005, Microsoft has moved to a unified build environment. All projects now use MSBuild facilities to generate CLR assemblies. The most exciting, and beneficial, aspect of this change is that Visual Studio is no longer required to compile and build applications; builds can be completely automated without it. MSBuild is distributed with the WinFX SDK.
If you're using Visual Studio to edit XAML and associated codebehind files, don't worry about the details of MSBuild. The relevant files are generated automatically by Visual Studio.
MSBuild is similar to ANT and Unix/Linux make facilities. MSBuild reads in XML-based project files, conventionally named with a .proj extension, and executes the tasks contained in the project file to produce the desired target.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
XAML Applications and Visual Studio
Inhaltsvorschau
Working in Visual Studio, you'll be able to select a number of WinFX Applications, and the project files and application manifest will be generated automatically. You can choose to create a WinFX Windows executable, a WinFX WebBrowser application, a WinFX Service Library (which creates a WinFX library comprising the definition and implementation of a WinFX Service), or a WinFX Custom Control Library (for extending WinFX controls). However, you'll still have to edit both the XAML and associated C# or VB.NET codebehind files manually.
If you've downloaded and installed the WinFX extensions for Visual Studio 2005, fire up the IDE. Choose Create Project and you'll be presented with a list of options, as illustrated in Figure 2-3.
Figure 2-3: WinFX application options in Visual Studio 2005
To create an application, choose either WinFX Windows Application or WinFX WebBrowser Application, depending on whether you want to deploy the application as an executable or for use within a web browser. Give the project a name and click OK. Visual Studio automatically generates the default XAML and codebehind files. In Figure 2-4, you can see that it has generated Windows1.xaml (Example 2-5) and Windows1.xaml.cs (Example 2-6). The language of the codebehind file depends on your choice of .NET-supported languages. I have chosen C#, so the generated files will reflect that choice.
Figure 2-4: Default files generated by Visual C# 2005 Express Edition
There are some minor differences between creating a WinFX WebBrowser and WinFX Windows application that occur whether or not you use Visual Studio. In a WebBrowser application, the default start page's root element is
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 3: The Basics of XAML
Inhaltsvorschau
XAML is an XML-based markup language. Given that, it shares many properties with other XML documents, such as case sensitivity and having to be well-formed. XAML has some specific syntax peculiarities designed for easing the declaration of specific types of elements. It provides abbreviated markup syntax for specific types of elements that take advantage of the underlying Common Language Runtime (CLR) class constructors.
This chapter will examine the core XAML syntax, as well as some of the peculiarities of its abbreviated markup syntax, in preparation for understanding more complex concepts in later chapters.
XAML generally follows XML syntax rules, just as any other XML-based markup language does. Each XAML element has a name and one or more attributes. Attributes correspond directly to object properties, and the name of the XAML element exactly matches the name of a CLR class definition.
XAML is pure markup, which means that while the names of event handlers are specified as attributes, you must implement the actual logic of the event handler in code. If you're familiar with ASP.NET programming techniques, then you'll be familiar with the term codebehind, which refers to the code "behind" a XAML interface element that is responsible for providing application logic such as event handlers. It can be implemented in either C# or VB.NET. In both cases, the code can be placed inline in the XAML file, although this contradicts best practices in separating the presentation and application logic layers.
How does this work? Every event in XAML can be assigned to a codebehind handler, which is implemented in a supported .NET language. For example, it's a common task to do something when a Button is clicked. So, first a Button is declared with the XAML code shown in Example 3-1.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Core XAML Syntax
Inhaltsvorschau
XAML generally follows XML syntax rules, just as any other XML-based markup language does. Each XAML element has a name and one or more attributes. Attributes correspond directly to object properties, and the name of the XAML element exactly matches the name of a CLR class definition.
XAML is pure markup, which means that while the names of event handlers are specified as attributes, you must implement the actual logic of the event handler in code. If you're familiar with ASP.NET programming techniques, then you'll be familiar with the term codebehind, which refers to the code "behind" a XAML interface element that is responsible for providing application logic such as event handlers. It can be implemented in either C# or VB.NET. In both cases, the code can be placed inline in the XAML file, although this contradicts best practices in separating the presentation and application logic layers.
How does this work? Every event in XAML can be assigned to a codebehind handler, which is implemented in a supported .NET language. For example, it's a common task to do something when a Button is clicked. So, first a Button is declared with the XAML code shown in Example 3-1.
Example 3-1. XAML Button declaration

    <Button

        OnClick="ButtonClickedHandler"

        Name="MyButton"

        Width="50"

        Content="Click Me!" />

Then, a corresponding codebehind handler is declared, and, when the Button is clicked, the handler is automatically executed (Examples 3-2 and 3-3).
Example 3-2. Button OnClick handler in C#

    void ButtonClickedHandler(object sender, RoutedEventArgs eventArgs)

    {

          MyButton.Width = 100;

          MyButton.Content = "Thank you!";

    }

Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Elements
Inhaltsvorschau
All XAML elements are an XML representation of CLR classes, but not all CLR classes are represented in XAML. Most of those represented are user-interface elements and are ultimately derived from System.Windows.UIElement, which provides basic visual user-interface properties that are shared by most XAML elements . A System.Windows.UIElement can render itself, receive input via the keyboard and mouse, visually size and position its child elements, and raise events.
Not all XAML elements are derived from System.Windows.UIElement. Some, such as LineBreak, TableColumn, and Document, are derived from System.Windows.Frame-workContentElement. System.Windows.FrameworkContentElement elements cannot render themselves but are instead rendered by another class, usually the container in which they have been placed.
Most XAML elements can be organized into five basic categories:
  • Root elements
  • Control elements
  • Panel elements
  • Shape and geometric elements
  • Document elements
Root elements function as the page's base container for all user-interface elements. A page is required to have one root element. The most commonly used root elements are the panel elements—StackPanel, DockPanel, Canvas, and Grid—and Page, a root element that allows you to declaratively control a number of the properties of the window containing the XAML page. To be considered a root element, the element must be a container for at least one other element. (When displaying XAML output in XamlPad, you don't have to include a root element because XamlPad provides it on your behalf.) You can create custom root elements by deriving new classes from Page or Window and exposing them as XAML elements.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Attributes
Inhaltsvorschau
Attributes are the XML representation of the properties of an element's corresponding CLR class. The Width attribute of the XAML Button element corresponds directly to the Width property of the System.Windows.Button class. To show the correlation between XAML and CLR classes, Examples 3-7 and 3-8 declare a Button instance and its attributes in both XAML and C#.
Example 3-7. Button declared in XAML

    <Button

         Width="100"

         Name="myButton"

         Height="20"

         Content="This is my button" />

Example 3-8. Button declared in C#

    Button myButton;

    myButton.Width=100;

    myButton.Height=20;

    myButton.Content = "This is my button";

As with the XAML tags for elements, attributes are spelled exactly the same as their corresponding CLR class properties. (Width = Width, Content = Content . . . You get the picture.)
There are two types of XAML attributes. The first, dependency properties, are public static read-only fields on CLR classes that are derived from DependencyProperty and have declared CLR accessor methods. In other words, the value of dependency properties can be dependent on (hence the name) other variables in CLR classes and, therefore, can only be accessed with a public get or set accessor method to be evaluated properly.
Dependency properties are like stock certificates. The stock certificate represents a value (money), but the actual amount of money it is worth (its value) is determined by external calculations and can change at nearly any time. To determine the value of your stock certificate, you must consult the stock exchange and do some multiplication. Dependency properties can also be based on external resources and often rely on calculations to determine their value.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Attached Properties
Inhaltsvorschau
A few XAML elements have attributes that are declared in other elements rather than in the element itself. These attributes are called attached properties . Attached properties are generally used to position elements within a parent element. Two elements with attached properties are Grid and DockPanel. Grid uses attached properties to describe the row and column in which an element should be contained. DockPanel uses attached properties to describe the location within the panel where an element should be placed.
Attached properties can be set on any element that derives from DependencyObject. UIElement derives from DependencyObject, so the requirement is met by most XAML elements.
Attached properties are declared in an element by using a reference to the element and the attribute being declared in the following manner: AttachPropertyProvider.PropertyName . For example, Grid has two attached properties: Row and Column. An element contained within a specific row/column combination in a grid would specify the row as an attribute with the name Grid.Row and the column similarly as Grid.Column. Example 3-14 describes the use of these attached properties.
Example 3-14. Using the attached properties of Grid

    <Grid

        ShowGridLines="true">

        <ColumnDefinition

             Width="50"/>

        <ColumnDefinition

             Width="50"/>

        <RowDefinition

             Height="100" />

        <RowDefinition

             Height="25" />

        <RowDefinition

             Height="25" />

        <TextBlock

             Grid.Column="0"

             Grid.Row="0">Col 0, Row 0

        </TextBlock>

        <TextBlock

             Grid.Column="1"

             Grid.Row="0">Col 1, Row 0

        </TextBlock>

        <TextBlock

             Grid.Column="0"

             Grid.Row="1">Col 0, Row 1

        </TextBlock>

        <TextBlock

             Grid.Column="1"

             Grid.Row="1">Col 1, Row 1

        </TextBlock>

    </Grid>

Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Binding Properties
Inhaltsvorschau
Another mechanism in XAML that can be used to declare the value of attributes is a bind declaration . A bind declaration allows you to set an attribute's value by referencing the value of another element. Bind declarations must be attached to a specific dependency property of a target element. Remember that dependency properties are static read-only properties of a CLR class that are exposed only through get and set accessor methods to support concepts such as binding. Properties are bound together in a bind declaration using the Binding element.
Binding elements are used to bind the source to target elements. If the dependency properties in the source elements change when the application runs, the dependency properties in the target elements will change as well. Basically, you're telling an attribute that its value should always be determined by evaluating some other attribute or data source. It's like assigning a value to one variable by assigning it to another, as shown in the following example:

    int a = 1;

    int b;

    b = a;

The difference between code-based variable assignments and XAML binding is that in XAML, the association is permanent. The assignment of b = a in the code example happens only once, and, if a changes later, b doesn't follow suit. In XAML, the Binding keyword ties the values together permanently.
The syntax for a Binding element is as follows:

    <ElementName Attribute="{Binding Path=SimpleProperty, Mode=OneTime} />

The curly braces are a general indicator to the parser that the value contained in the braces is not a simple value. Instead, the first keyword within the braces indicates the type of special handling needed. The Binding statement at the beginning of the string indicates a binding declaration.
An example of how binding works is when you are tying together the content of two different elements, such as a Button and a TextBlock. In Example 3-15, every time the Button is clicked, the C# code (Example 3-16) in its
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
codebehind
Inhaltsvorschau
The concept of codebehind has been mentioned but not fully explored yet. You've already noted that event handlers can be assigned to elements and implemented in code and that the attribute name must exactly match the handler name in code. The event handlers specified by name as attributes for controls are associated with the codebehind in a C# or VB.NET file during the compilation process. The compiler generates a partial class for XAML and then assembles it with the code, which defines the rest of the class in a codebehind file. This allows the two pieces to be tied together when the code is interpreted within the runtime engine.
But there are other things that can be accomplished in code besides handling events. Many applications require initialization of data sources, or automatically adding fields to the user interface depending on the user's role. These things cannot be done in XAML; they must be done programmatically.
Every XAML application represents the declaration of a partial CLR class. Part of the class is declared using XAML, and the rest of it can be declared in a codebehind file using C# or Visual Basic. The implementation can then programmatically modify the user interface or interact with other systems such as a database or remote application to accomplish the application's designated task.
As with event handlers, the name of the class assigned as the implementation class for a XAML application must exactly match, including the namespace. For example, the XAML class declaration in Example 3-18 referencing the StartPage class with a namespace of MyNameSpace exactly matches the name of the class in Example 3-19. Note that the Page element in the XAML file has no other elements. The TextBlock and Button seen in Figure 3-7 are the result of programmatically adding the two elements to the Page in the C# codebehind implementation.
Example 3-18. XAML declaration of StartPage.xaml

    <Page xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

          xmlns:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 4: Layout and Positioning
Inhaltsvorschau
One of the most important facets of user-interface design is the layout and positioning of elements on the page. The user interface must be pleasing to the eye without being cluttered, and it must enhance productivity through ease of use. Elements should be paired with visual clues such that their use is intuitive, which reduces the amount of learning time required.
One of the primary mechanisms for building an intuitive, usable user interface is layout elements. Layout elements position elements on the screen and insure that they are grouped together in a way that enhances readability. XAML offers a plethora of options for page layout and user-interface construction. Margins, padding, and panels provide basic layout capabilities that can be combined to position elements exactly where you want them on the page.
The largest hurdle to building a user-interface layout is the variation in screen resolution and size among end users. This is especially true for applications loaded in a web browser. There are several mechanisms available through scripting and CSS to counter the layout problems inherent in serving a wide variety of screen resolutions and sizes .
XAML addresses these issues by dynamically sizing elements relative to the size of the page in which they are placed. All XAML elements will stretch to fit their entire container, unless you indicate otherwise. If the default container is a page 800 pixels wide, then all elements added to the page will size themselves to be 800 pixels wide. Similarly, if the page is resized, the elements will dynamically resize themselves to fit the page.
While this resizing behavior is needed to handle varying window sizes, it isn't necessary for elements to take up the entire screen. This chapter examines the XAML elements and attributes that control the layout and size of elements on the page while maintaining the flexibility that dynamic sizing offers.
The two most commonly used
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
StackPanel and DockPanel
Inhaltsvorschau
The two most commonly used Panel subclasses are StackPanel and DockPanel. Both are used for relative positioning of elements and automatically handle placement of elements based on the order in which they are declared.
The differences between the two types of Panel can be summed up as follows:
StackPanel
Defaults to automatically rendering elements in the order in which they are declared in the XAML file, from top to bottom.
DockPanel
Defaults to automatically rendering elements in the order in which they are declared in the XAML file, from left to right.
The attached attributes of DockPanel can be used to alter the relative positioning of child elements.
The concept is best illustrated by recreating the user login interface (from Chapter 3) using both types of panels. The result is shown in Figure 4-1. The elements of this user login interface are each added in the following order:
  1. The Username Label element
  2. The username TextBox
  3. The Password Label element
  4. The password PasswordBox
  5. The Submit Button element
Figure 4-1: Positioning elements with StackPanel and DockPanel
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Width and Alignment
Inhaltsvorschau
By default, XAML renders elements on the screen in the order in which they are defined within the XAML file. If the TextBox in Example 4-2 is added to the StackPanel before the first Label, then it will appear as the first element and the Label will appear after it. By default, all elements have a width equal to the container element of which they are children. Using the login page example from Chapter 3 without specifying any kind of formatting or layout restrictions yields the user interface in Figure 4-6.
Figure 4-5: Using DockPanel.Dock to position elements
Example 4-2. Example code for user login screen with no layout or formatting

<Page

    xmlns="http://schemas.microsoft.com/winfx/avalon/2005">

    <StackPanel 

>

        <Label>Username</Label>

        <TextBox>username@example.com</TextBox>

        <Label>Password</Label>

        <PasswordBox></PasswordBox>

        <Button Content="Submit" />

    </StackPanel>

</Page>

This is neither aesthetically pleasing nor is it particularly usable. There is no clear delineation between elements, and it is hard on the eyes. The first thing to do is limit the width of the elements to make them easier to read. There are three options to accomplish this: define the Width attribute on all the elements added to the StackPanel, limit the width of the StackPanel itself, or change the HorizontalAlignment of the StackPanel. The second option will force all the elements in the StackPanel to be the same width. While this is a viable option, it may not be appropriate for every situation, especially if you don't want all the elements to be the same width as the TextBox. The best option in this case is to limit the width of each individual element. Note that specifying the
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Margins and Padding
Inhaltsvorschau
If you're familiar at all with CSS, then you're familiar with the concept of padding and margins. Padding and margins assist user-interface designers in positioning elements and content in elements. The two attributes are both described by a Thickness element but serve different purposes in layout.
Margin describes the distance between the element and its children or peers. It is used to position elements relative to other elements. Using abbreviated markup syntax, you can specify its thickness as a uniform distance around the element, e.g., Margin=" 20 ", or as the distance in each individual direction in terms of left, top, right, and bottom (in that order), e.g., Margin=" 20 , 10 , 20 , 10 ".
Margin is one of the elements that does not require commas in its abbreviated markup. It can be described using either comma- or space-separated values.
Specifying a Margin value on the StackPanel in our user-login example will only change the distance between the StackPanel and the edges of the Page. To illustrate the concept of Margin, examine Figure 4-10. A second StackPanel has been added, containing the same elements for the user-login interface as well as borders to illustrate the Margin property at work. (In order to produce a side-by-side comparison of two StackPanel elements, both were enclosed in a DockPanel.) The black-bordered StackPanel has no Margin at all, while the lighter-bordered StackPanel has a uniform Margin of 20 device-independent pixels. You can see the difference in the positioning of the elements in relation to their children. The
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Grid
Inhaltsvorschau
The Grid element is useful for relative, automatic positioning strategies in which some control over element placement is required. Grid is similar to Table (just like the HTML Table) and provides individual cells in which elements can be positioned. Grid is more complex than Table, however, and should not be treated as a simple Table element. Grid cell sizes can be explicitly declared as a number of device-independent pixels, as a percentage of the overall available Width and Height, or as auto-size factors based on their content by using the enumeration Auto.
Grid, like DockPanel, uses attached attributes to position child elements. Grid uses two attached attributes, Row and Column, to determine placement of child elements within its cells.
Grid uses zero-based indexing when specifying Row and Column placement.
A sample Grid might appear as follows:
Column 0, Row 0
Column 1, Row 0
Column 2, Row 0
Column 0, Row 1
Column 1, Row 1
Column 2, Row 1
To add elements to the Grid, specify which row and column the element is being added to. For example, to add an element to the cell in Column 1, Row 1, you would declare the element like this:
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Absolute Positioning
Inhaltsvorschau
Thus far, StackPanel, DockPanel, and Grid elements have been used to position elements on the Page. Positioning with these Panel elements is a purely relative positioning strategy and offers no control over the x- and y-coordinate values of the element's position. Like CSS, relative positioning is used to allow elements to flow and reposition in the event that the page size changes. There are times, however, when absolute positioning is desired. XAML supports absolute positioning through the use of the Canvas element.
All elements on a Canvas element must be absolutely positioned or they will stack on top of one another. Absolute positioning is accomplished using the attached attributes of Canvas, namely Top, Left, Bottom, and Right.
If specified, the attached attributes Top or Left take priority over Bottom or Right.
The coordinate system used to position elements places 0,0 in the upper-left corner of the Canvas. Values specified for Top, Left, Bottom, and Right are relative to the Canvas, not the Page. If the Page contains only a single Canvas, then the value is relative to both, but only because the Canvas ends up positioned with 0,0 in the same place as 0,0 on the Page.
So, absolute positioning is actually relative, in an absolute kind of way. An example is probably in order after that mouthful. Figure 4-13 shows the relativity of absolute positioning. A Canvas has been added to a Canvas, specifying Top and Left values of 100 and 200, respectively. The unboxed coordinates are Label elements added to the parent Canvas, while the boxed coordinates are those added to the second Canvas. The Labels were added with the same Top and Left coordinates, but you can see that the Labels added to the second (the child) Canvas are offset. The code producing Figure 4-13 is shown in Example 4-6.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 5: Resources
Inhaltsvorschau
Every XAML element has a collection of resources . Resources provide a mechanism for defining common styles or elements that can be reused throughout the user interface. They also configure the actions that are carried out when a user interacts with a display element.
The benefit of using resources to define reusable, common styles is that modifications can be applied to one element, but they will take effect throughout the entire application. This reduces the chance of error and the possibility that an element might be missed when changes are applied. For example, you may want to define a specific Point from which all geometric shapes will originate. By defining the Point as a resource and referencing it as the appropriate attribute value of geometric elements, the origination point can easily be changed in one place—the resource declaration—without concern for mistakes made in multiple places throughout the user interface.
Local resources are defined on the element, while global resources are defined on the root element. Global resources can be used by all elements in the page while local resources are reserved for use by the element in which they are declared. Regardless of the type of resource (local or global), the syntax used to declare the resources is the same.
Although every element has a collection of resources, they are usually declared only on the root element.
When adding resources, you must add the appropriate namespace to the root element. You'll also need to give it a name to differentiate it from the default namespace. The default namespace, which references Avalon, contains the definitions of Avalon elements, such as Button, Page, and StackPanel. The namespace that must be added to define resources is the XAML namespace and describes the language itself.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Resources
Inhaltsvorschau
When adding resources, you must add the appropriate namespace to the root element. You'll also need to give it a name to differentiate it from the default namespace. The default namespace, which references Avalon, contains the definitions of Avalon elements, such as Button, Page, and StackPanel. The namespace that must be added to define resources is the XAML namespace and describes the language itself.
Because resource definitions require the use of XAML-specific tags—which are not described by the default namespace—you must declare a reference to the XAML namespace and use it to prefix those attributes found only there, such as Key.
The key is a fully qualified attribute comprising the namespace, a colon, and the keyword Key. Elements defined as a resource must have a declared "key name" to be referenced by other elements. The value of the attribute is the name by which the resource will be referenced by other elements.
Resources are added by explicitly declaring elements as children of the Resources attribute of an element.
In Example 5-1, there are two instances of SolidColorBrush defined as resources: RedBrush and BlueBrush.
Example 5-1. Using resources to define global styles

<Page

    xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

    xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"

    <Page.Resources>

        <SolidColorBrush

            x:Key="RedBrush"

            Color="red"/>

        <SolidColorBrush

            x:Key="BlueBrush"

            Color="blue"/>

    </Page.Resources>

    <StackPanel>

        <Button

            Background="{StaticResource RedBrush}" />

        <Ellipse

            Fill="{StaticResource BlueBrush}"

            Margin="40"

            Width="15"

            Height="
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Using Styles
Inhaltsvorschau
A Style is a set of properties applied to an element that can be used to describe the appearance of an element. It is used in a similar manner as styles declared in CSS. A style can be applied locally to a single element, or it can be declared globally and referenced from the element. Styles can also be declared such that they affect all instances of a given type, such as Button.
A XAML Style is a collection of one or more Setter elements that act upon a specified dependency property, such as Background or Foreground. Remember that a Key value is required if the style will be applied by reference to an element. In Example 5-4, the Style MyStyle is declared as the value of the Style element on the Button, which sets the background, foreground, and width attributes to the values specified by the Style declaration.
Example 5-4. Example style applied to a Button element

<Page

    xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

    xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">

    <Page.Resources>

        <Style

            x:Key="MyStyle">

           <Setter

                Property="Control.Background"

                Value="Red" />

           <Setter

                Property="Control.Foreground"

                Value="White" />

           <Setter

               Property="Control.Width"

               Value="100" />

        </Style>

    </Page.Resources>

    <StackPanel>

        <Button

            Style="{StaticResource MyStyle}"

            Content="A Red Button"/>

    </StackPanel>

</Page>

Figure 5-1 shows the result of evaluating Example 5-4 in XamlPad.
Figure 5-1: Application of a global style to a Button
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Triggers
Inhaltsvorschau
Triggers allow you to change attributes of an element when a specific action occurs. For example, you can change the font color of text when the mouse hovers over it, or change the width of a button once it has been clicked. Triggers can act on single instances of an element, or affect an entire class of elements.
Triggers are conditional. They are essentially a way to implement standard if...then logic without writing external code. In other words, a trigger evaluates an attribute and if the current value of that attribute matches the value specified by the trigger, then the style is applied. If the cursor moves over a Button, then change the background to green.
Example 5-7 defines a style that targets all elements of type Button. The code adds a Trigger that will fire when the property Button.IsMouseOver is true. Two Setter elements define the attributes we wish to change when the condition of the Trigger is met. In this case, it changes the foreground of the Button to green and the background to red.
Example 5-7. Using a Trigger to modify the appearance of Button elements

<Page

    xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

    xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">

    <Page.Resources>

        <Style

            TargetType="{x:Type Button}">

            <Style.Triggers>

                <Trigger

                    Property="Button.IsMouseOver"

                    Value="true">

                    <Setter

                        Property = "Foreground"

                        Value="Green"/>

                    <Setter

                        Property = "
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 6: Storyboards and Animations
Inhaltsvorschau
In the past, animations in user interfaces have been left to specialized developers and graphic designers. Most animations used in web applications require expertise in technologies such as Flash or GIF (Graphics Interchange Format). While these technologies vastly differ in how animations are created, they both utilize the basic building block of animation—frames.
The new presentation subsystem in Windows Vista (provided through the WinFX runtimes for Windows 2003 and XP) also supports the concept of animation using frames. In frame-based animation, each frame contains an object to be animated. That animation might be a change of color over time or movement from one point to another. Each frame specifies the state of the object at a given point in time. In frame 1, the circle is blue; in frame 2, it is blue-green; in frame 3, it is green, etc.
Flash developers have long been able to apply common animations to objects such as color changes, fades, and movement. Windows developers, however, had no such mechanism, so the task of coding such animations was time-consuming and difficult. XAML offers the ability to animate elements with the same ease as other technologies, making standard animations a breeze to create while providing the framework for more complex animations.
XAML uses storyboards to create animations. Standard animations, including fades, color changes, transforms, and even position changes, are easily accomplished through XAML—without any code—by using storyboards.
One of the hardest pieces of animations to nail down is timing . Timing involves determining how long an animation will last and how long each frame within it should take. If an object is being changed from green to blue, how long should each stage of the color change take? At what point does the object start looking more blue than green? And even more difficult, how many color changes (frames) will it take to go from blue to green in the time allotted for the total animation?
Thankfully, Avalon provides an efficient timing system that no longer requires a developer to manage timers himself. Instead, timing and redrawing the screen is handled by Avalon and defined in XAML. Like all XAML elements,
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Storyboards
Inhaltsvorschau
Storyboards can only be defined on root elements or as part of a style, even though every framework element has a Storyboard collection. The difference between setting the Storyboard attribute of the root element and setting the Storyboard attribute of a style can be summed up as follows:
  • A style-based Storyboard can be applied to any element, not just the root element.
  • The target of each SetterTimeline is assumed to be the element for which the style is defined, so you do not specify the SetterTimeline object's TargetName.
Every Storyboard must have at least one SetterTimeline. A SetterTimeline describes the target of the animation and the attribute being animated. In order to animate an attribute, it must be a dependency property. Animation in XAML is accomplished by modifying the value of an attribute over time. A Path indicates the element and the attribute to modify. The Path is another name for the target of an animation . An example of this is (Button.Width) or (Button.Height).
The target is declared using the following syntax:

    (ElementName.AttributeName)

Example 6-1 shows the XAML for targeting the width of a button with an animation.
Example 6-1. Targeting an element in a SetterTimeline

<SetterTimeline

             TargetName="
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Controlling Animations
Inhaltsvorschau
Animation elements inherit several attributes from Timeline that control the speed and behavior of the animation. One of the more useful attributes is SpeedRatio, which controls the speed at which the animation moves. The attribute AutoReverse is also noteworthy. AutoReverse controls the behavior of the Timeline when it reaches the end of its Duration. Setting this value to true will cause the animation to reverse itself when it reaches the end of its iteration. Setting it to false will cause the animation to begin again—if RepeatBehavior indicates that it should continue—either for a specified number of iterations through the animation, for a specified period of time, or forever.
Example 6-6 shows the same animation from Example 6-4, but RepeatBehavior is now declared as 2x and AutoReverse has been added and set to true. This animation will repeat twice, reversing itself each time. Although the animation declaration makes it appear that the Button will have a yellow background at the end of the animation, the background will actually be blue because we have set AutoReverse to true.
Example 6-6. Modifying the behavior of an Animation using AutoReverse and RepeatDuration

<Page

     xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

     xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">

     <Page.Storyboards>

         <SetterTimeline

             TargetName="myButton"

             Path="(Button.Background).(SolidColorBrush.Color)">

             <ColorAnimation

                 From="Blue"

                 To="Yellow"

                 Duration="0:0:5"

                 AutoReverse="true"

                 RepeatBehavior="
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Animation Using Key Frames
Inhaltsvorschau
KeyFrame animations are another method for animating elements in XAML. They differ from non-key animations in that they use a number of key frames (values) as the destination rather than allowing the system to iterate through the values. KeyFrame animations allow you to control the specific values—and the interpolation methods used to arrive at them—across a number of key frames that make up the animation.
KeyFrame animations use different classes than non-key frame animations, but they are easily recognizable because each one uses the term "KeyFrame" in its name. As with non-key animations, there are KeyFrame animations for almost every primitive data type and some XAML elements.
Creating a KeyFrame animation requires the following steps:
  1. Set a Duration for the animation.
  2. For each key frame, select its appropriate type, set its value and key time, and add it to the animation's KeyFrame collection.
  3. Associate the animation with an element's attribute, just as you would for a non-key animation.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 7: Elements
Inhaltsvorschau
XAML elements are components whose primary purpose is to display information either graphically or textually. They are used to create and display text and graphics either as standalone elements or as ones nested within controls.Users do not generally interact with elements unless they are nested within a control, such as using an Image to paint the foreground of a Button or defining a Hyperlink within a TextBlock.
Many of the elements in XAML, particularly those such as Brush and Color, are used as attributes for other elements and derive from System.Windows.DependencyObject . DependencyObject is a standard .NET object and can be used by developers to create their own custom attributes.
Bold
Hierarchy: DependencyObject → ContentElement → FrameworkContentElement → TextElement → Inline

<Bold>Text to be bold</Bold>

<Bold .../> is an Inline-derived class that is applied to text-based elements. Bold makes the font appear darker, increasing its weight. Its only properties are those inherited from Inline. (See Figure 7-1.)
Figure 7-1: Bold text
Brush
Hierarchy: DependencyObject → Freezable → Animatable
<Brush .../> is an abstract component that defines how an area is painted. SolidColorBrush is most commonly referenced by other components through the use of the predefined colors in the Colors class (see Appendix G).
When a Brush is referenced as one of the colors from Colors, no explicit declaration is required and the element may be referenced simply by its predefined color name. (See Example 7-1.)
Example 7-1. Implicit declaration of a Brush using a predefined color
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 8: Controls
Inhaltsvorschau
With the exception of Hyperlink, which is included because it is unique among non-control elements in its support of the Click event, all controls in this chapter belong to the System.Windows.Controls namespace and are ultimately children of the same base class, Control. This gives them a common set of properties and events, but this chapter will detail those specific to each control. Two controls, Grid and StackPanel, are not detailed in this chapter because they provide layout control and are therefore documented in Chapter 10.
Because XAML controls represent .NET CLR controls, they share a common hierarchy (UIElementFrameworkElementControl). For the most part, these base classes are abstract and will never be explicitly declared as XAML elements. Their attributes are inherited by subclasses and have been included to avoid redundancy. Each element description contains a hierarchy so that you can easily reference the inherited attributes.
Attributes that have both a get and set method are generally accessible through XAML, and these values are set in exactly the same way as the properties detailed below. Although an attribute's data type may be type Boolean or Integer, XAML requires that the attribute value be specified as a String. Some elements have attached attributes. These are specifically designated as such, and the concept behind them is discussed in depth in Chapter 3.
There are several structures and elements, detailed in other chapters, that are commonly used to declare attributes. For example, Thickness, detailed in Chapter 7, is the data type for several common Control attributes, such as Margin and Padding. Similarly, Brush is used to describe how to fill the Background attribute of elements. Brush is most often described as a simple, predefined Color (see Appendix G). Table 8-1 lists these common structures/elements, as well as where they are detailed.
Table 8-1: Structures and elements commonly used as attribute types
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Base Control Reference
Inhaltsvorschau
This section details the attributes associated with the hierarchy common to controls. It includes the attributes for UIElement, FrameworkElement, and the Control classes (ContentControl, ItemsControl, HeaderedItemsControl, and HeaderedContentControl).
UIElement
UIElement is the base class for most XAML controls. It provides attributes that determine how elements are displayed.
Attributes
AllowDrop
This Boolean value determines whether the element can be the target of a drag-and-drop operation.
true
The element may be targeted.
false
The element may not be targeted. This is the default.
Opacity
This Double value describes the opacity factor applied to the element when it is rendered. The range for this value is 0.0-1.0. The default value is 1.0.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Common Event Reference
Inhaltsvorschau
Elements deriving from UIElement inherit a set of common events. Events are used in XAML to specify the codebehind handler that will be executed when the specified event is raised. All events can be assigned a codebehind handler using the following syntax:

<Element Name="ElementName" EventName="CodeBehindHandler" />

Elements specifying a codebehind handler must declare the Name attribute in order to be referenced in the codebehind class. Examples 8-2 and 8-3 demonstrate the event-handling code in C# and VisualBasic, respectively, which is executed when the mouse cursor enters or leaves the Button declared in Example 8-4.
Example 8-2. C# implementation of event handlers

public partial class MouseEnterMouseLeave

{

    void MouseEnterHandler(object sender, MouseEventArgs e)

    {

        MyButton.Background=Brushes.Red;

        MyButton.Content="Mouse is over me";

    }

    void MouseLeaveHandler(object sender, MouseEventArgs e)

    {

        MyButton.Background=Brushes.White;

        MyButton.Content="Mouse is not over me";

    }

}

Example 8-3. VisualBasic implementation of event handlers

Partial Public Class MouseEnterMouseLeave

    Sub MouseEnterHandler(ByVal sender as Object, ByVal e As MouseEventArgs

        MyButton.Background = Brushes.Red

        MyButton.Content = "Mouse is over me"

    End Sub

    Sub MouseLeaveHandler(ByVal sender As Object, ByVal e as MouseEventArgs

        MyButton.Background = Brushes.White

        MyButton.Content = "Mouse is not over me"

    End Sub

End Class

Example 8-4. XAML declaration of event handlers for Button

<StackPanel

    xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

    xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"

    
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Core Control Reference
Inhaltsvorschau
Button
Hierarchy: UIElement → FrameworkElement → Control → ContentControl → ButtonBase

<Button

    Click="OnSubmitButtonClicked">

    Button Label

</Button>

or:

<Button

    Click="OnSubmitButtonClicked"

    Content="Button Label" />

<Button .../> displays a push button.
Attributes
Click (optional)
This attribute sets the name of the codebehind handler that executes when the button is clicked.
Content (optional)
This attribute sets the value that is displayed on the button.
Events
Click
CheckBox
Hierarchy: UIElement → FrameworkElement → Control → ContentControl → ButtonBase → ToggleButton

<CheckBox

    IsChecked="true|false"

    Content="This box is checked"

    IsCheckedChanged="OnCheckedChangedEvent" />

or:

<CheckBox

    IsChecked="true|false"

    IsCheckedChanged="OnCheckedChangedEvent">

        This is a checkbox label

</CheckBox>

<CheckBox .../> displays a checkbox.
Attributes
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 9: Shapes and Geometry
Inhaltsvorschau
Shape and Geometry are both used to render 2-D objects. While the two have much in common, there are important differences between the two sets of drawing objects. The most important is that instances of Geometry cannot draw themselves; they must be drawn by another class. There are other differences, but the easiest way to differentiate the two is to remember that Geometry is used to describe a region and Shape determines how that region is drawn and filled. Because Shapes are UI elements, they can be used inside panels and most controls. Geometry elements cannot.
Geometry elements are also used to define clipping regions . A clipping region defines the visible area of another element, such as an Image. For example, if you have a large image but only want to display part of it, you could use a Geometry element to clip it. You could also use Geometry elements to clip the image to simulate a frame, as Example 9-1 and Figure 9-1 illustrate.
Example 9-1. Clipping an image with EllipseGeometry

<StackPanel

    xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

    Margin="20">

    <Image

        Source="c:\image.jpg"

        HorizontalAlignment="Left">

        <Image.Clip>

            <EllipseGeometry

                RadiusX="100"

                RadiusY="75"

                Center="100,75"/>

        </Image.Clip>

    </Image>

</StackPanel>

Figure 9-1: Using EllipseGeometry to clip an image
Geometries are categorized as either simple or path. A simple geometry is used to describe basic geometric shapes, such as line, ellipse, and rectangle. Path geometry describes more complex geometric figures, such as ones created by tracing a path.
Although shapes are most commonly drawn on a Canvas, they may be used with any Panel or control that supports non-text elements. This chapter details the shapes and geometry available for use in XAML.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 10: Layout
Inhaltsvorschau
The elements in this chapter are all used to position and decorate content on a page. Some elements are controls, such as Grid and StackPanel, while others are documents, such as FixedDocument. These elements have been grouped together because they are all focused on laying out the page, either by controlling the rendering and positioning of elements or by using it as a container of specific content types.
Border
Hierarchy: UIElement → FrameworkElement → Decorator

    <Border

        Height="25"

        Background="White"

        BorderBrush="Black"

        BorderThickness="1"

        CornerRadius="20"

        Padding="2 2 2 2">

    </Border>

<Border .../> draws a border, background, or both around an element (Figure 10-1). Only elements contained within a parent Border element can display a border.
Border can have only one child. To display multiple children, an additional Panel element needs to be placed within the parent Border. Child elements can then be placed within that Panel element.
Attributes
Background (optional)
Describes the Brush used to fill the interior of the element.
BorderBrush (optional)
Describes the Brush used to paint the border.
Figure 10-1: Border
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 11: Animations and Transformations
Inhaltsvorschau
Animations and transformations provide a way to modify an element's attributes over time without requiring code. The concepts behind animation and transformations are explored more deeply in Chapter 6.
AnimationTimeline
Hierarchy: DependencyObject → Freezable → Animatable → Timeline
<AnimationTimeline .../> is a base class for a number of other abstract classes that can animate specific types of data. All the derived classes are the same, except for the type of data they are intended to animate. A few derived classes specifically implement a separate Animation, such as ColorAnimation and DoubleAnimation.
All of the Type AnimationBase elements have at least one subclass that can animate the data type supported by using a collection of KeyFrame elements. Each subclass is appropriately named Type AnimationUsingKeyFrames. These elements are identical to each other in functionality; they simply require the use of a data type-specific KeyFrame, which is named using the format Type KeyFrame. Each Type KeyFrame element is detailed in this chapter. For example, the BooleanAnimationBase element has one subclass, BooleanAnimationUsingKeyFrames, which requires a collection of BooleanKeyFrame elements as its children.
Example 11-1 offers a DoubleAnimationUsingKeyFrames as a template for how to use the classes derived from AnimationTimeline.
Example 11-1. A DoubleAnimationUsingKeyFrames definition

<DoubleAnimationUsingKeyFrames

    Duration="0:0:15"

    FillBehavior="HoldEnd">

    <DoubleAnimationUsingKeyFrames.KeyFrames>

        <LinearDoubleKeyFrame

            Value="500"

            KeyTime="0:0:7|Uniform|Paced|30%" />

        <LinearDoubleKeyFrame

            Value="200"

            KeyTime="0:0:10|Uniform|Paced|30%" />

        <LinearDoubleKeyFrame

            Value="
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Chapter 12: Events
Inhaltsvorschau
In a typical application, UI elements will contain other elements as children. A Page contains a Button and a Label; a StackPanel might contain multiple Button elements as well as text-based and Image elements. UI elements and their children are designed with user interaction in mind. When a user interacts with an element, a corresponding event is raised and—if declared—an event handler is executed. When a Button is clicked, the Click event is raised; when the selection in a ComboBox changes, the SelectionChanged event is raised; and so on. Chapter 8 notes the events raised by controls along with each element and lists the common events for all controls.
While this material is likely familiar to developers, there is a fundamental difference in how Avalon elements deal with events. In a typical Windows Forms or other Microsoft .NET application, only the element that raised the event responds to the event. If a Button is clicked by a user, the Button element receives the corresponding event indicating that the button has been clicked. In a XAML application, the parent element of the Button may handle the event instead, or any other element in the tree in which the Button is declared.
Consider the following XAML application (Figure 12-1) and its XAML code (Example 12-1).
Figure 12-1: A simple XAML application
Example 12-1. A simple XAML application

<Page

    xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

    xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005">

    <Border

        Margin="10"

        Padding="10"

        BorderBrush="Black"

        Background="SkyBlue"

        BorderThickness="1">

        <StackPanel

            Margin="10">

            <Button

                Content="Click me" />

        </StackPanel>

    </Border>

</Page>

The application consists of four elements: Page, Border, StackPanel, and Button. Button is a child of
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Routing Strategies
Inhaltsvorschau
There are three types of routed event strategies in Avalon: bubble, direct, and tunnel:
Bubble
A bottom-up routing strategy. The target element is first notified, then its parent, then its parent, and so on. If the event is marked Handled, then no other event handlers will be invoked. Microsoft suggests marking an event as Handled as soon as you know that there are no further elements along the route because there are performance advantages to keeping the codepath as short as possible.
Direct
The type of routing strategy used by Windows Forms and other Microsoft .NET libraries. Direct routing means that only the event source element is notified. If the event was raised by a Button, then only the Button in question will receive notification. Very few UI events in Avalon use the direct-routing strategy.
Tunnel
Works in the opposite direction as bubble; it starts at the root of the tree and works down, stopping with the target element. Tunneling events are prefixed in Avalon with the word Preview. Generally, there is a corresponding bubble event for each tunnel event. If the tunnel event is named PreviewKeyDown, then the bubble event is called KeyDown. Similarly, if there is a bubble event called KeyUp, then there is likely a tunneling event called PreviewKeyUp.
Because of tunneling and bubbling, parent elements often receive events when the source is one of their child elements. If necessary, the source of the event can be determined programmatically by accessing the Source property of the EventArgs parameter passed to the event handler, as in Example 12-3.
Not all events are routed. The XAML designer will need to know whether they are, because routed events can be used within styles to created triggers; non-routed events cannot. Events are specifically marked as routed or non-routed to assist the XAML designer with trigger creation.
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Event Argument Reference
Inhaltsvorschau
The signature for event handlers is primarily the same for all events; only the event argument changes for different types of events. The syntax for all event handlers is:

    C#:

        public void HandlerName(Object sender, EventArgs e)

    Visual Basic:

        Sub HandlerName(ByVal sender As Object, ByVal e As EventArgs)

Each event argument type holds values specific to the event as well as general data such as the source element and the original source element. This section details the event argument types.
RoutedEventArgs
RoutedEventArgs is the base class for many other routed event argument types and is also the argument type passed to the event handler for events such as Click and Closed.
Properties
Handled
This Boolean designates whether the event has been handled. If it is set to true, then no other event handlers will be invoked.
OriginalSource
OriginalSource is stored as an Object and is generally cast to FrameworkElement in order to determine its true type. OriginalSource is the original element that raised the event.
RoutedEvent
This
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Event Reference
Inhaltsvorschau
Click
Routed Event
Yes
Elements

MenuItem

Hyperlink

ButtonBase

Description
Click is raised on an element's MouseLeftButtonDown and MouseRightButtonDown events.
Event Argument Type

RoutedEventArgs

Closed
Routed Event
Yes
Elements

ContextMenu

ToolTip

Popup

Pag

Windo

NavigationWindow

Description
Closed is raised when the element has closed.
Event Argument Type

RoutedEventArgs

DragEnter
Routed Event
Yes
Elements

UIElement

Description
DragEnter is raised when an underlying system drag event is raised, with either this element or a child element along the route as the target. The corresponding event is PreviewDragEnter.
Event Argument Type

RoutedEventArgs

DragLeave
Routed event
Yes
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix A: System.Windows.Controls
Inhaltsvorschau
When writing code for event handlers, it is sometimes necessary to include the namespace in which specific elements reside. Here are the elements found in the System.Windows.Controls namespace:
  • Border
  • Button
  • Canvas
  • CheckBox
  • ColumnDefinition
  • ColumnDefinitionsCollection
  • ComboBox
  • ComboBoxItem
  • ContextMenu
  • DockPanel
  • DocumentViewer
  • Expander
  • Frame
  • Grid
  • HorizontalSlider
  • Image
  • Label
  • ListBox
  • ListBoxItem
  • MediaElement
  • Menu
  • MenuItem
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix B: System.Windows.Documents
Inhaltsvorschau
When writing code for event handlers, it is sometimes necessary to include the namespace in which specific elements reside. Here are the elements found in the System.Windows.Documents namespace:
  • Bold
  • Figure
  • FixedDocument
  • FixedPage
  • Floater
  • FlowDocument
  • Hyperlink
  • Inline
  • Italic
  • LineBreak
  • List
  • ListItem
  • PageContent
  • Paragraph
  • Section
  • Subscript
  • Superscript
  • Table
  • TableFooter
  • TableBody
  • TableCell
  • TableColumn
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix C: System.Windows.Shapes
Inhaltsvorschau
When writing code for event handlers, it is sometimes necessary to include the namespace in which specific elements reside. Here are the elements found in the System.Windows.Shapes namespace:
  • Ellipse
  • Line
  • Path
  • Polygon
  • Polyline
  • Rectangle
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix D: System.Windows
Inhaltsvorschau
When writing code for event handlers, it is sometimes necessary to include the namespace in which specific elements reside. Here are the elements found in the System.Windows namespace:
  • Application
  • DataTemplate
  • Setter
  • Style
  • TextDecoration
  • Trigger
  • Window
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix E: System.Windows.Media
Inhaltsvorschau
When writing code for event handlers, it is sometimes necessary to include the namespace in which specific elements reside. Here are the elements found in the System.Windows.Media namespace:
  • ArcSegment
  • BezierSegment
  • Brush
  • CloseSegment
  • Colors
  • CombinedGeometry
  • DashStyle
  • Drawing
  • DrawingBrush
  • DrawingCollection
  • DrawingGroup
  • EllipseGeometry
  • Geometry
  • GeometryCollection
  • GeometryDrawing
  • GeometryGroup
  • GradientBrush
  • GradientStop
  • ImageBrush
  • LinearGradientBrush
  • LineGeometry
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix F: System.Windows.Input.ApplicationCommands
Inhaltsvorschau
In XAML, MenuItem can be assigned to any one of the common commands provided by Windows. Here are the commands found in the namespace System.Windows.Input.ApplicationCommands and descriptions of what each command represents:
Close
Represents the Close command
ContextMenu
Represents the Context Menu command
Copy
Represents the Copy command
CorrectionList
Represents the Correction List command
Cut
Represents the Cut command
Delete
Represents the Delete command
Find
Represents the Find command
Help
Represents the Help command
New
Represents the New command
Open
Represents the Open command
Paste
Represents the Paste command
Print
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix G: Predefined Colors
Inhaltsvorschau
The Brush element is often assigned by using a predefined color name such as Red or Blue. The following are the predefined colors supported in XAML for this purpose:
AliceBlue
DarkKhaki
GreenYellow
AntiqueWhite
DarkMagenta
HoneyDew
Aqua
DarkOliveGreen
HotPink
Aquamarine
DarkOrange
IndianRed
Azure
DarkOrchid
Indigo
Beige
DarkRed
Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
Appendix H: XAML Interface in Code
Inhaltsvorschau
Anything in XAML can be done programmatically, due to the fact that XAML elements represent classes in WPF. Consider the following XAML declaration of a simple application:

    <Page

        xmlns="http://schemas.microsoft.com/winfx/avalon/2005"

        xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" >

        <StackPanel>

        <StackPanel

            Orientation="Vertical"

            Width="100"

            HorizontalAlignment="Left" >

               <TextBlock>First Block of Text</TextBlock>

               <Button

                Content="Button 1" />

           </StackPanel>

        <StackPanel

            Orientation="Vertical"

            Width="100"

            HorizontalAlignment="Left" >

               <TextBlock>Second Block of Text</TextBlock>

               <Button

                Content="Button 2" />

           </StackPanel>

        </StackPanel>

    </Page>

The following C# code declares the same controls and elements described in the preceding XAML declaration. Note that the C# code requires many more lines than the XAML representation, and the XAML representation is much clearer in terms of the hierarchy of elements. These are two of the advantages of using XAML over procedural code to declare a user interface.

    using System;

    using System.Collections;

    using System.Text;

    using System.Windows;

    using System.Windows.Controls;

    using System.Windows.Documents;

    using System.Windows.Navigation;

    using System.Windows.Media;

    using System.Windows.Media.Imaging;

    using System.IO;

    using System.Threading;





    namespace SimpleApplication

    {

      public class MyApplication : Application

      {

        TextBlock txtElement1;

        TextBlock txtElement2;

        StackPanel rootPanel;

        Button btnElement1;

        StackPanel panel1;

        StackPanel panel2;

        Button btnElement2;

        Window win;



        protected override void OnStartup(StartupEventArgs e)

        {

           win = new System.Windows.Window(  );

           rootPanel = new StackPanel(  );



           panel1 = new StackPanel(  );

           panel1.Orientation= System.Windows.Controls.Orientation.Vertical;

           panel1.HorizontalAlignment=System.Windows.HorizontalAlignment.Left;

           panel1.Width=100;

           txtElement1 = new TextBlock(  );

           txtElement1.Text = "First Block of Text";

           btnElement1 = new Button(  );

           btnElement1.Content = "Button 1";

           panel1.Children.Add(txtElement1);

           panel1.Children.Add(btnElement1);



           panel2 = new StackPanel(  );

           panel2.Orientation= System.Windows.Controls.Orientation.Vertical;

           panel2.HorizontalAlignment=System.Windows.HorizontalAlignment.Left;

           panel2.Width=100;

           txtElement2 = new TextBlock(  );

           txtElement2.Text = "Second Block of Text";

           btnElement2 = new Button(  );

           btnElement2.Content = "Button 2";

           panel2.Children.Add(txtElement2);

           panel2.Children.Add(btnElement2);



           win.Content = rootPanel;

           rootPanel.Children.Add(panel1);

           rootPanel.Children.Add(panel2);

           win.Show(  );

        }

      }



      internal sealed class Test

      {

        [System.STAThread(  )]

        public static void Main(  )

        {

          MyApplication app = new MyApplication(  );

          app.Run(  );

        }

      }

    }

Ende der Inhaltsvorschau. Der weiterere Inhalt dieses Abschnitts ist hier nicht einsehbar.
	

Zurück zu XAML in a Nutshell


Themen

Buchreihen

Special Interest

International Sites

O'Reilly China O'Reilly USA O'Reilly Japan O'Reilly Taiwan