2.3. Building XAML ApplicationsWhile 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.
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. There are a number of XML elements that can be used in a project file. This discussion covers only the basic elements and the typical ways that they are used to create an Avalon project file. The following list describes the key elements in an Avalon project file:
There are a multitude of options that can be configured with MSBuild. It is a very rich schema designed to handle building targets in a dynamic environment. The following code illustrates the minimum requirements for a project file: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <AssemblyName>MyFirstApplication</AssemblyName> <TargetType>winexe|exe|library|module</TargetType> <OutputPath>.\</OutputPath> </PropertyGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" /> <ItemGroup> <ApplicationDefinition Include="MyApp.xaml" /> <Page Include="Page1.xaml" /> </ItemGroup> <ItemGroup> <Reference Include="System"> <Private>false</Private> </Reference> <Reference Include="System.Xml"> <Private>false</Private> </Reference> <Reference Include="System.Data"> <Private>false</Private> </Reference> <Reference Include="WindowsBase"> <Private>false</Private> </Reference> <Reference Include="PresentationCore"> <Private>false</Private> </Reference> <Reference Include="PresentationFramework"> <Private>false</Private> </Reference> <Reference Include="WindowsUIAutomation"> <Private>false</Private> </Reference> <Reference Include="UIAutomationProvider"> <Private>false</Private> </Reference> </ItemGroup> </Project> The most important piece of the project file is the ItemGroup, which specifies the inclusion of the XAML files that make up your project. You'll need one ApplicationDefinition file, identified by the <ApplicationDefinition .../> element, and one or more page definition files, included through the use of the <Page .../> element. You can set a few optional attributes in the PropertyGroup element:
MSBuild relies on a number of environment variables related to the location of libraries and the identification of the .NET Framework version used to build the application. The WinFX SDK includes a batch file to appropriately set these environment variables. The necessary variables are: SET FrameworkVersion=v2.0.50215 SET FrameworkDir=%windir%\Microsoft.NET\Framework SET WinFX=%ProgramFiles%\Reference Assemblies\Microsoft\WinFX\%FrameworkVersion% SET URT=%FrameworkDir%\%FrameworkVersion% SET WinFXSDK=C:\Program Files\Microsoft SDKs\WinFX SET FrameworkSDKDir=%WinFXSDK%\ SET WinFXSDKTOOLPATH=%WinFXSDK%\bin SET PATH=%URT%;%WinFXSDKTOOLPATH%;%WinFXSDK%\vc\bin;%path%; SET INCLUDE=%WinFXSDK%\Include;%WinFXSDK%\vc\Include; SET LIB=%WinFXSDK%\Lib;%WinFXSDK%\vc\Lib; After the environment variables have been set and the project file is appropriately configured for your application target, execute MSBuild on the command line to generate your application. When completed, you will see several files:
When you run MSBuild, the files are parsed into two corresponding files: a C# generated file, identified by the extension .g.cs (the g stands for generated, the cs for C#), and a BAML file, identified by the .baml extension. These files are automatically placed into a created subdirectory that is named according to the Configuration property located in the PropertyGroup section of the project file. For a release configuration, the subdirectory is called obj\Release. Similarly, the obj\Debug hierarchy is used for a Debug configuration. The class files generated from markup are partial class files. A class file containing the implementation of event handlers and other application logic will be merged with the generated partial class file during compilation.
The C# files are then compiled into an assembly. The assembly is named according to the AssemblyName attribute and placed into the location referenced by the OutputPath attribute. All that remains of the markup is the BAML, which is deserialized into CLR objects at runtime by the System.Windows.Serialization.Parser class. This class can be used to (de)serialize any BAML or XAML at runtime. If you generated a Windows executable, you can now double-click on the name of the file or run it from the command line. If you specified the creation of a hosted application, you'll need to load the .xbap file from Microsoft Internet Explorer, which will launch the presentation manager and run the application. Running the Windows executable defined in the previous section generates the application in Figure 2-2. You'll note that there are similarities and differences between the preview shown in Figure 2-1 and the application shown in Figure 2-2. XamlPad, one of the tools installed with XAML, is an excellent real-time What You See Is What You Get (WYSIWYG) environment for playing around with XAML, but it does not support the full definition of an application. Because NavigationWindow is used as the root element for this application, the application automatically inherits a navigation "chrome" at the top of the application, with forward and back buttons similar to those used in Internet Explorer to navigate through web pages. Aside from this difference, the resulting page appears the same. Figure 2-2. MyFirstApplication |