A XAML File as a Class Declaration


The application definition file is the XAML file that defines the class of your application s Application object. However, in general, a XAML document is simply a file that defines a class. The class produced by the XAML definition derives from the class associated with the XML document s root element name. By default, the build system uses the XAML base file name as the generated class name .

Creating an Application Definition File for a Navigation Application

Recall that the Item element with Type of ApplicationDefinition specifies the name of the XAML file that defines the Application object. In other words, this element specifies the XAML file that contains the entry point for your application. The Longhorn platform will create an instance of the MSAvalon.Windows.Application -derived type that you define in this file and let it manage the startup, shutdown, and navigation of your application.

In Chapter 1, you saw how to create and use an application instance programmatically. The following XAML file uses markup to define the Application object for a project:

 <NavigationApplication xmlns="http://schemas.microsoft.com/2003/xaml" 
StartupUri="HelloWorld.xaml" />

I expect that most Longhorn applications will be navigation-based applications and, therefore, will often just reuse the standard NavigationApplication object. You can reuse this application definition file for most of your navigation-based applications by changing only the value of the StartupUri attribute.

For example, if the previous application definition resides in the HelloWorldApplication.xaml file and I use the HelloWorld.proj project file listed previously, the build system produces the following class declaration:

 namespace IntroLonghorn { 
class HelloWorldApplication :
MSAvalon.Windows.Navigation.NavigationApplication {

}
}

The namespace results from the DefaultClrNameSpace declaration in the project file, the declared class name is the same as the base file name, and the declared class extends the class represented by the root element in the XAML file.

Customizing the Generated Code Using Attributes

When you declare a root element in a XAML file, you can use attributes on the root element to control the name of the generated class declaration. You can use any of the following optional attributes:

  • A namespace prefix definition that associates a prefix with a namespace named Definition . You must define a prefix for this namespace to use the Language and Class attributes. Traditionally, the def prefix is used.

  • A Language attribute (defined in the Definition namespace) that specifies the programming language used by any inline code in the XAML file.

  • A Class attribute (defined in the Definition namespace) that specifies the name of the generated class. When you specify a name containing one or more periods, the build system does not prefix the name with the DefaultClrNameSpace value.

As an example, let s change the contents of the HelloWorldApplication.xaml file to the following:

 <NavigationApplication xmlns="http://schemas.microsoft.com/2003/xaml" 
xmlns:def="Definition"
def:Class="Special.MyApp"
def:CodeBehind="HelloWorldApplication.xaml.cs"
StartupUri="HelloWorld.xaml" />

The generated class would then be this:

 namespace Special { 
class MyApp :
MSAvalon.Windows.Navigation.NavigationApplication {

}
}

Using Code and Markup in the Same Class

Nearly all applications will require you to write some code ”for example, a click event handler for a button or a virtual method override ”in addition to the markup that specifies the UI. Recall from Chapter 1 that my non-navigation- based application overrode the OnStartingUp method to create its window and controls. I ll rewrite that example to illustrate how you would combine application code and markup.

While this forthcoming example creates a non-navigation application, I want to emphasize that there is really no compelling reason to create such an application. You can always create a navigation-based application that never actually navigates to a different page. However, writing such an application requires me to mix code and markup in the same class therefore provides a good example.

Recall that creating a non-navigation application requires you to define a custom class that inherits from MSAvalon.Windows.Application and that overrides the OnStartingUp method. The application definition file declares the application object class that your program uses. Therefore, a non-navigation application must define its overriding OnStartingUp method in the same class.

Except for the following changes, an application configuration file for a non-navigation application contains the same items as a definition file for a navigation application:

  • The root element is Application instead of NavigationApplication .

  • The file must contain or reference the implementation of the OnStartingUp method for your application class.

Because I need to use markup and code to implement a single class, I need to show you a technique to associate a source code file with a XAML file.

Associating a Source-Behind File with a XAML File

You will frequently want to develop portions of your application by using markup and to develop other parts by using a more traditional programming language. I strongly recommend separating the UI and the logic into individual source files by using the following technique.

You can add a XAML CodeBehind element (defined in the Definition namespace) to the root element of any XAML file and specify the name of a source code file (also known as the code-behind file ). The build engine will compile the XAML declarations into a managed class. The build system also compiles the code-behind file into a managed class declaration. The tricky aspect is that both of these class declarations represent partial declarations of a single class.

Here s a XAML definition that produces a non-navigation application class equivalent to the first example in Chapter 1:

 <Application xmlns="http://schemas.microsoft.com/2003/xaml" 
xmlns:def="Definition"
def:Language="C#"
def:Class="IntroLonghorn.CodeBehindSample"
def:CodeBehind="CodeBehind.xaml.cs" />

There are two noteworthy aspects to this application definition file:

  • The Language attribute specifies that the code-behind file contains C# source code.

  • The CodeBehind attribute specifies that the source file name is CodeBehindMySample2.xaml.cs.

Here s the matching source-behind file:

 namespace IntroLonghorn { 
using System;
using MSAvalon.Windows;
using MSAvalon.Windows.Controls;
using MSAvalon.Windows.Media;

public partial class CodeBehindSample {
MSAvalon.Windows.Controls.SimpleText txtElement;
MSAvalon.Windows.Window mainWindow;

protected override
void OnStartingUp (StartingUpCancelEventArgs e) {
base.OnStartingUp (e);
CreateAndShowMainWindow ();
}

private void CreateAndShowMainWindow () {
// Create the applications main window
mainWindow = new MSAvalon.Windows.Window ();

// Add a dark red, 14 point, "Hello World!" text element
txtElement = new MSAvalon.Windows.Controls.SimpleText ();
txtElement.Text = "Hello World!";
txtElement.Foreground = new
MSAvalon.Windows.Media.SolidColorBrush (Colors.DarkRed);
txtElement.FontSize = new FontSize (14,
FontSizeType.Point);
mainWindow.Children.Add (txtElement);
mainWindow.Show ();
}
}
}

Notice the partial keyword in the class declaration in the code-behind file. This keyword states that the compiler should merge this class definition with other definitions of the same class. This allows you to provide multiple partial definitions of a class, each in a separate source file, that the compiler combines into a single class definition in the resulting assembly.

Mixing Source Code and Markup in a Single XAML File

I think it s just wrong to mix source code and markup in the same file. I even considered not showing you how to do it. However, some evildoer somewhere will write a sample program using this technique, so you might need to understand what he has done. Moreover, you can then use the code-behind file approach described previously to rid the world of a small amount of evil and separate the UI from the logic.

Here s an application definition file with the source code inserted directly inline with the markup:

 <Application xmlns="http://schemas.microsoft.com/2003/xaml" 
xmlns:def="Definition"
def:Language="C#"
def:Class="IntroLonghorn.MySample2" >

<def:Code>
<![CDATA[
protected override void OnStartingUp (StartingUpCancelEventArgs e) {
base.OnStartingUp (e);
CreateAndShowMainWindow ();
}
. . . Remaining methods elided for clarity
]]>
</def:Code>
</Application>

In this example, the Language attribute specifies that the inline source code is C#. Notice that the Code element is a CDATA block containing the inline source code. It s sometimes technically necessary to enclose inline source code in an XML CDATA block to ensure that the document is well-formed. In fact, the XAML parser always requires you to enclose the inline source code in a CDATA block, even when omitting it produces a well- formed document.

I apologize once again for showing you such a travesty.




Introducing Microsoft WinFX
Introducing WinFX(TM) The Application Programming Interface for the Next Generation of Microsoft Windows Code Name Longhorn (Pro Developer)
ISBN: 0735620857
EAN: 2147483647
Year: 2004
Pages: 83
Authors: Brent Rector

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