WEBSITE

Introducing Windows Presentation Foundation and XAML : Building WPF Applications Using Visual Studio 2010 (part 2)

11/6/2012 12:57:21 AM

3. Designing the GUI of our Window

The WPF API supports the ability to load, parse, and save XAML descriptions programmatically. Doing so can be quite useful in a variety of situations. For example, assume you have five different XAML files that describe the look and feel of a Window type. As long as the names of each control (and any necessary event handlers) are identical within each file, it would be possible to dynamically apply "skins" to the window (perhaps based on a startup argument passed into the application).

Interacting with XAML at runtime revolves around the XamlReader and XamlWriter types, both of which are defined within the System.Windows.Markup namespace. To illustrate how to programmatically hydrate a Window object from an external *.xaml file, you will build an application that mimics the basic functionality of the kaxaml.

While your application will certainly not be as feature-rich as kaxaml.exe, it will provide the ability to enter XAML markup, view the results, and save the XAML to an external file. To begin, update the initial XAML definition of your <Window> as:


<Window x:Class="MyXamlPad.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="My Custom XAML Editor"
  Height="338" Width="1041"
  Loaded="Window_Loaded" Closed="Window_Closed"
  WindowStartupLocation="CenterScreen">

  <!-- You will use a DockPanel, not a Grid -->
  <DockPanel LastChildFill="True" >

    <!-- This button will launch a window with defined XAML -->
    <Button DockPanel.Dock="Top" Name = "btnViewXaml" Width="100" Height="40"
            Content ="View Xaml" Click="btnViewXaml_Click" />

    <!-- This will be the area to type within -->
    <TextBox AcceptsReturn ="True" Name ="txtXamlData"
             FontSize ="14" Background="Black" Foreground="Yellow"
             BorderBrush ="Blue" VerticalScrollBarVisibility="Auto"
             AcceptsTab="True"/>
  </DockPanel>
</Window>

					  

First of all, notice that you have replaced the initial <Grid> with a <DockPanel> type that contains a Button (named btnViewXaml) and a TextBox (named txtXamlData), and that the Click event of the Button type has been handled. Also notice that the Loaded and Closed events of the Window itself have been handled within the opening <Window> element. If you have used the designer to handle your events, you should find the following code in your MainWindow.xaml.cs file:

public partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();
  }

  private void btnViewXaml_Click(object sender, RoutedEventArgs e)
  {
  }

  private void Window_Closed(object sender, EventArgs e)
  {
  }

  private void Window_Loaded(object sender, RoutedEventArgs e)
  {
  }
}

Before continuing, be sure to import the following namespaces into your MainWindow.xaml.cs fMainWindow.xaml.cs file:

using System.IO;
using System.Windows.Markup;

4. Implementing the Loaded Event

The Loaded event of your main window is in charge of determining if there is currently a file named YourXaml.xaml in the folder containing the application. If this file does exist, you will read in the data and place it into the TextBox on the main window. If not, you will fill the TextBox with an initial default XAML description of an empty window (this description is the exact same markup as an initial window definition, except that you are using a <StackPanel> rather than a <Grid>).

NOTE

The string you are building to represent the key XML namespaces is a bit cumbersome to type, given the escape characters required for the embedded quotations, so type carefully.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
  // When the main window of the app loads,
  // place some basic XAML text into the text block.
  if (File.Exists(System.Environment.CurrentDirectory + "\\YourXaml.xaml"))
  {
    txtXamlData.Text = File.ReadAllText("YourXaml.xaml");
  }

else
  {
    txtXamlData.Text =
    "<Window xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n"
    +"xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n"
    +"Height =\"400\" Width =\"500\" WindowStartupLocation=\"CenterScreen\">\n"
    +"<StackPanel>\n"
    +"</StackPanel>\n"
    +"</Window>";
  }
}

					  

Using this approach, your application will be able to load the XAML entered in a previous session or supply a default block of markup if necessary. At this point, you should be able to run your program and find the display shown in Figure 7 within the TextBox type.

Figure 7. The first run of MyXamlPad.exe

5. Implementing the Button's Click Event

When you click the Button, you will first save the current data in the TextBox into the YourXaml.xaml file. At this point, you will read in the persisted data via File.Open() to obtain a Stream-derived type. This is necessary, as the XamlReader.Load() method requires a Stream-derived type (rather than a simple System.String) to represent the XAML to be parsed.

Once you have loaded the XAML description of the <Window> you wish to construct, create an instance of System.Windows.Window based on the in-memory XAML and display the Window as a modal dialog:

private void btnViewXaml_Click(object sender, RoutedEventArgs e)
{
  // Write out the data in the text block to a local *.xaml file.
  File.WriteAllText("YourXaml.xaml", txtXamlData.Text);

  // This is the window that will be dynamically XAML-ed.
  Window myWindow = null;

// Open local *.xaml file.
  try
  {
    using (Stream sr = File.Open("YourXaml.xaml", FileMode.Open))
    {
      // Connect the XAML to the Window object.
      myWindow = (Window)XamlReader.Load(sr);

      // Show window as a dialog and clean up.
      myWindow.ShowDialog();
      myWindow.Close();
      myWindow = null;

    }
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message);
  }
}

Note that you are wrapping much of our logic within a try/catch block. In this way, if the YourXaml.xaml file contains ill-formed markup, you can see the error of your ways within the resulting message box. For example, run your program, and purposely misspell <StackPanel> by adding an extra letter P in the opening element or whatnot. If you click the button, you will see an error similar to Figure 8:

Figure 8. Catching markup errors

6. Implementing the Closed Event

Finally, the Closed event of your Window type will ensure that the latest and greatest data in the TextBox is persisted to the YourXaml.xaml file:

private void Window_Closed(object sender, EventArgs e)
{
  // Write out the data in the text block to a local *.xaml file.
  File.WriteAllText("YourXaml.xaml", txtXamlData.Text);
}

7. Testing the Application

Now fire up your program and enter some XAML into your text area. Do be aware that (like kaxaml.exe) this program does not allow you to specify any code generation–centric XAML attributes (such as Class or any event handlers). As a test, enter the following XAML within your <Window> scope:

<StackPanel>
  <Rectangle Fill = "Green" Height = "40" Width = "200" />
  <Button Content = "OK!" Height = "40" Width = "100" />
  <Label Content ="{x:Type Label}" />
</StackPanel>

Once you click the button, you will see a window appear that renders your XAML definitions (or possibly you'll see a parsing error in the message box—watch your typing!). Figure 9 shows possible output.

Figure 9. MyXamlPad.exe in action

Great! I am sure you can think of many possible enhancements to this application, but to do so you need to be aware of how to work with WPF controls and the panels that contain them.

Other  
 
Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone
Visit movie_stars's profile on Pinterest.