One More Application Style-Windows Presentation Foundation


Microsoft, considering the issues of both of the application styles, created a new application style that works to combine the best of both these models. WPF applications can run as a thick-client application (directly from an executable) or even within the browser. Microsoft has spent a considerable amount of time building an application model that focuses on the user interface of the application. The graphic capabilities of the WPF application style are completely new and are expected to revolutionize how applications behave. The graphic capabilities are more Flash-like and fluid than the traditional thick- client application. It includes a vector-based composition engine that makes full use of the end user's high-powered graphic card. WPF offers many more capabilities in its framework. These capabilities are presented in Figure 26-2.

image from book
Figure 26-2

As you can see, XAML is one of the base services. As stated earlier, you can use XAML as a means to build an application through the process of declarative programming. For instance, you can create an instance of a button using C# programming as shown in the following code:

      Button myButton = new Button();      myButton.Content = "This is my button text";      myButton.Background = new SolidColorBrush(Colors.Yellow); 

Or you can use XAML to accomplish the same thing:

      <Button Name="button1" >This is my button text         <Button.Background>            Yellow         </Button.Background>      </Button> 

In the end, either of these methods produces the same results. The C# code found in a class file actually gets compiled and run to produce a large button on the page, whereas the XAML code is interpreted into a class file that is compiled and produces the same large button. Building WPF applications using XAML allows you to separate business logic from presentation. This feature has demonstrated value within the ASP.NET world that uses the same model. Using XAML is easy, and you can work with any type of tool to build your WPF application-including Notepad!

XAML enables you to point to events that happen within a code-behind page just as ASP.NET does in its declarative model. For instance, working with the button example presented in the first part of the chapter, you can add a click event by using the Click attribute (as shown in Listing 26-2):

Listing 26-2: Window1.xaml

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="300" Width="300"          >        <Grid>          <Button Margin="10,10,0,0" Name="button1" Click="button1_Click" Height="23"           HorizontalAlignment="Left" VerticalAlignment="Top" Width="75">           Button</Button>          <Label Margin="16.37,44.7233333333334,22,24" Name="label1" FontWeight="Bold"           FontSize="150" FontFamily="Verdana">1</Label>        </Grid>      </Window> 
image from book

In this case, you add a reference through the use of the Click attribute for a button1_Click method. This means that whenever the button is actually clicked on the form, the button1_Click event is triggered.

In addition to the new Button control, a Label control has been added. The Label control, label1, has a defined margin (which you can get pretty exact about if you look closely at the numbers). If you attempt to design this same thing using Visual Studio 2005, your form in the design surface would resemble the screen shown in Figure 26-3.

image from book
Figure 26-3

The Click attribute points to an event that is contained within the code-behind file for this form-Window1.xaml.cs. This file is presented in Listing 26-3.

Listing 26-3: Window1.xaml.cs

image from book
      using System.Windows;      using System.Windows.Controls;      namespace XAML_Example      {          /// <summary>          /// Interaction logic for Window1.xaml          /// </summary>          public partial class Window1 : System.Windows.Window          {              int buttonValue = 1;              public Window1()              {                  InitializeComponent();              }              void button1_Click(object sender, RoutedEventArgs e)              {                  buttonValue += 1;                  this.label1.Content = buttonValue.ToString();              }          }      } 
image from book

In this case, when the button on the form is clicked, the button1_Click event is triggered. This increases the buttonValue variable by one and assigns its value to the Content attribute of the label1 control (its text value). This means that every time the button on the form is clicked, the number shown on the form is increased by one.

WPF Within Visual Studio 2005

WPF applications can be built directly within Visual Studio 2005. It requires a toolkit called the Visual Studio 2005 Extensions for .NET Framework 3.0. After the toolkit is installed, you should find that you have project types that are relevant to the .NET Framework 3.0. This is illustrated in Figure 26-4, which shows the project dialog box in Visual Studio 2005 after the installation of the toolkit.

image from book
Figure 26-4

A new view of the WPF application has been incorporated into Visual Studio 2005, as shown in Figure 26-5.

image from book
Figure 26-5

This example presents a Design view of the project showing the WPF form as it would appear when compiled and run. You can also see another view of the same form in XAML. Like most .NET applications built from Visual Studio, it enables you to drag and drop controls directly onto the design surface of the WPF form or to type the controls directly into the XAML document using declarative programming.

Nesting Controls

Through XAML, you can add hierarchy to your controls. XML is a hierarchal language, and you can add that same level of hierarchy to deal with controls in your applications. For instance, in the ListBox control, you can normally insert textual items directly in the selectable options for the end user. This is presented in Listing 26-4.

Listing 26-4: Showing three elements within the ListBox control

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="300" Width="300" Width="300"          >          <Grid>            <ListBox Margin="15,15,15,110" Name="listBox1">              <Label Name="label1" Content="Hello, I'm a Label Control" />              <Label Name="label2" Content="Hello, I'm a Label Control" />              <Image Name="image1" Source="whiteLipper.gif" />            </ListBox>          </Grid>      </Window> 
image from book

In this case, you have a ListBox control with three child elements. Interestingly, two of the selectable elements are Label controls, whereas the third element is an image. You can nest pretty much anything that you want within something else. WPF takes on the Parent-Child relationship. Please note that images have to be included in the solution for this to work. The preceding bit of XAML code produces the results shown in Figure 26-6.

image from book
Figure 26-6

From this example, you can see that this ListBox takes traditional text such as the first two items shown in the figure. The third item is the most interesting because it is an image. It is just as selectable as the textual items. They are all simply child elements of the parent ListBox control.

This type of nesting capability can be used in many places. For instance, to use the same logo image within a button, you simply nest the image within the <Button> control as shown in Listing 26-5.

Listing 26-5: Nesting an image within a Button control

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="300" Width="300"          >          <Grid>             <Button Height="45" HorizontalAlignment="Left" Margin="25,0,0,55"              Name="button1" VerticalAlignment="Bottom" Width="87">                <Image Name="image1" Source="whiteLipper.gif" />             </Button>          </Grid>      </Window> 
image from book

This bit of code includes a typical <Button> control, but nested within the opening and closing <Button> elements is an Image control declaration. This produces the results presented in Figure 26-7.

image from book
Figure 26-7

Case Study: Building a Document Viewer Using XAML

Windows Presentation Foundation is very effective in the area of presentation. A tremendous amount of attention has been put onto layout, fonts, and vector graphics. A common practice is to view documents directly within an application-either documents that are created or contained within the application or documents that reside elsewhere. WPF is excellent at document presentation. This section, however, focuses on simply constructing and presenting a document directly from the XAML file.

Create the WPF Application

To accomplish this task, create a new WPF Application (WPF) project. First, you can expand the default form. From the Visual Studio toolbox, drag and drop a FlowDocumentReader control onto the design surface of the form. Initially, this gives you only a small navigation-like control that you can position on the page. You end up with something like the control shown in Figure 26-8.

image from book
Figure 26-8

In this figure, you see the navigation system for document viewing, which also includes the area in which you will present the document. In order to make room for the document that you create inside this control, expand the FlowDocumentReader control so that it takes up all the space on the form. Now that the control is in place on the form, the next step is to create the document to be presented.

Building the Document

For this part of the application, you build the entire document directly in the XAML file itself. At this stage, you XAML file should appear as illustrated in Listing 26-6.

Listing 26-6: The XAML document at this point

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="450" Width="800"          >        <Grid>          <FlowDocumentReader Margin="5,5,5,5" Name="flowDocumentReader1" />        </Grid>      </Window> 
image from book

Looking this code over, you can see a single <FlowDocumentReader> element on the form, positioned with a 5-pixel margin on each of its sides. At this point, the document reader is now in place on the form, but it doesn't contain a document of any kind. The next step is to build the document.

To accomplish this task, you nest some additional XML elements within the <FlowDocumentReader> element, such as a <FlowDocument>. You use these to define your document. Some of the child elements of the <FlowDocument> element include <BlockUIContainer>, <Paragraph>, <List>, <Section>, and <Table>.

The <BlockUIContainer> element allows you to position other WPF controls within the document. For instance, if you want to keep the title and text as presented in Listing 26-6, but you also want to include a RichTextBox control on the document; you simply use the <BlockUIContainer> illustrated in Listing 26-7.

Listing 26-7: Using the <BlockUIContainer> element in your document

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="450" Width="800"          >          <Grid>            <FlowDocumentReader Margin="5,5,5,5" Name="flowDocumentReader1">              <FlowDocument>                <Paragraph>                  <Italic><Bold>This is the title of the document</Bold></Italic>                </Paragraph>                <Paragraph>                  This is the start of the document ...                </Paragraph>                <BlockUIContainer>                  <RichTextBox Name="richTextBox11" />                </BlockUIContainer>              </FlowDocument>            </FlowDocumentReader>          </Grid>      </Window> 
image from book

Now the document that you are creating has three parts to it-two paragraph parts and a part that contains a single control (the RichTextBox control). Running this application produces the results presented in Figure 26-9.

image from book
Figure 26-9

You already saw the <Paragraph> section in action with the title and the plain text that was placed at the top of the document. Remember that items can nest inside each other quite easily in XAML, and this means that the <Section>, <List>, and <Table> elements allow for easy nesting of other elements, as does the base <Paragraph> element. For a good example of this, look at Listing 26-8 where you create some list items in the document using the <List> element.

Listing 26-8: Using the <List> element in your document

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="450" Width="800"          >          <Grid>            <FlowDocumentReader Margin="5,5,5,5" Name="flowDocumentReader1">              <FlowDocument>                <Paragraph>                  <Italic><Bold>This is the title of the document</Bold></Italic>                </Paragraph>                <Paragraph>                  This is the start of the document ...                </Paragraph>                <List>                  <ListItem>                   <Paragraph>                     Item One                   </Paragraph>                  </ListItem>                  <ListItem>                   <Paragraph>                     Item Two                   </Paragraph>                  </ListItem>                </List>              </FlowDocument>            </FlowDocumentReader>        </Grid>      </Window> 
image from book

You can see that a list is created using the <List> element within the <FlowDocument> element. The <List> element can take any number of <ListItem> elements that, in turn, can contain what you deem necessary. In this case, each list item is a <Paragraph> element. These two list items produce the results presented in Figure 26-10.

image from book
Figure 26-10

The nice thing about this control is that is allows you to easily display a large set of content in columns within the document viewer. To see this in action, go to the Lorem Ipsum Web site found at http://www.lipsum.com. This site enables you to generate a large amount of gibberish text to use in this example. To build your XAML document with this text, wrap each of the provided paragraphs in a <Paragraph> element. In the end, your XAML document should be similar to the one presented in Listing 26-9.

Listing 26-9: Building the main document using lorem ipsum text

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="450" Width="800"          >        <Grid>          <FlowDocumentReader Margin="5,5,5,5" Name="flowDocumentReader1">            <FlowDocument>              <Paragraph>                <Italic>                  <Bold>This is the title of the document</Bold>                </Italic>              </Paragraph>              <Paragraph>                Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent mattis                euismod eros. Aliquam lobortis rhoncus purus ...              </Paragraph>              <Paragraph>                Ut elit lectus, volutpat in, dictum vitae, faucibus vel, nisl. Integer                dictum pede vel lacus. Vestibulum turpis erat, gravida ...              </Paragraph>              <Paragraph>                Pellentesque habitant morbi tristique senectus et netus et malesuada                fames ac turpis egestas. Vivamus iaculis ...              </Paragraph>            </FlowDocument>          </FlowDocumentReader>        </Grid>      </Window> 
image from book

Important 

The code shown in this example is slimmed down for presentation purposes. The paragraphs are cut short, and the example you see in the figures for this example actually include 20 paragraphs instead of the three that are shown here.

In this case, you have a document that should include 20 <Paragraph> sections from the Lorem Ipsum site. The <Paragraph> section at the top represents the title of the document. When you run this application, you get the results presented in Figure 26-11.

image from book
Figure 26-11

Using this little bit of XAML code, you can easily place a document within the application. The FlowDocumentReader control does an excellent job of making your documents easy to read. Notice that the text is divided into two separate columns for easy readability. You can see at the bottom of the application that it contains eight pages. This is controlled by the amount of text contained in the application and the font size of the text. There are a number of features on the control toolbar at the bottom of the application.

Viewing the Document

On the left part of the control panel is a magnifying glass. When you click this icon, a text box appears next to it. This text box enables you to search through the document quite quickly and easily. To the right of the magnifying glass and the search text box, you see a navigation control that allows you to click the arrows that take you to the next page or the previous page. To the right of the navigation controls, are three page view controls. The three available page views include:

  • q Page Mode-This is the mode presented in Figure 27-11. It enables you to see a single page that usually includes multiple columns.

  • q Two Page Mode-This is similar to the Page Mode, but has two distinct pages within the application.

  • q Scroll Mode-Like a Web page, this mode allows you to see the document as a single and continuous page with the appropriate scroll bars for pages that are too long or wide.

You can see a good example of the Scroll Mode and the Two Page Mode in Figure 26-12.

image from book
Figure 26-12

The FlowDocumentReader control allows you to control how you read the document. You can not only change the page format, but you can also click the plus or minus sign in the control panel to manipulate the font size. Clicking the plus sign causes the text to get larger as you can see in Figure 26-13.

image from book
Figure 26-13

Another feature of the FlowDocumentReader control is that it adapts quite nicely to any resolution. For instance, Figure 26-14 shows what the document looks like when it is expanded to a larger resolution.

image from book
Figure 26-14

As you can see in Figure 26-14, the document has automatically expanded to take advantage of all the available real estate of the screen. You could also shrink the application so that it is quite small. The text adapts quite well to any situation.

Adding an Image to the Document

In some of the earlier XAML examples, you learned you can add anything you want to the document using the XAML declaration. To see this in more detail, you can add an image to the document. It is possible to add an image to the document directly in the XAML code. This is illustrated in Listing 26-10.

Listing 26-10: Adding an image to the document

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="450" Width="800"          >        <Grid>          <FlowDocumentReader Margin="5,5,5,5" Name="flowDocumentReader1">            <FlowDocument>              <Paragraph>                <Italic>                  <Bold>This is the title of the document</Bold>                </Italic>              </Paragraph>              <Paragraph>                Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent mattis                euismod eros. Aliquam lobortis rhoncus purus ...              </Paragraph>              <Paragraph>                Ut elit lectus, volutpat in, dictum vitae, faucibus vel, nisl. Integer                dictum pede vel lacus. Vestibulum turpis erat, gravida ...              </Paragraph>              <Paragraph>                Pellentesque habitant morbi tristique senectus et netus et malesuada                fames ac turpis egestas. Vivamus iaculis ...              </Paragraph>              <Paragraph>                <Image Source="Sunset.jpg" />                <Italic>This is an image.</Italic>              </Paragraph>            </FlowDocument>          </FlowDocumentReader>        </Grid>      </Window> 
image from book

In this case, after the third <Paragraph> element, another <Paragraph> element is added. This <Paragraph> element is put in place simply to define a place where you can put the image. In this case, the <Image> element is used; it requires only a Source attribute to point to the location of the image. To place the image within the document and to give the text below it a style that is different from the text of the main document, use the <Italic> element to apply style.

If you run the example, you see that the image is embedded in the overall document. This is illustrated in Figure 26-15.

image from book
Figure 26-15

Again, the FlowDocumentReader control makes some smart decisions about the image on your behalf. First off, the image shown in Figure 26-15 is much smaller than the actual image. The FlowDocumentReader control is sizing the image to fit in the column and treats the image much like it treats the rest of the text contained within the document. This is shown in Figure 26-16. When you enlarge the viewing area of the document, you can see that the image also is enlarged to take advantage of the new viewable area of the screen.

image from book
Figure 26-16

If you switch the document viewing mode to scroll mode, you also see that the image now fills the entire width of the screen.

Final Step: Saving the Document as an XPS File

The last step in working with the FlowDocumentReader control is to change the WPF application so that the document you created can be saved as an XPS document. XPS, or XML Paper Specification, is a paginated representation of electronic paper that is described in XML. This specification was developed by Microsoft.

XPS documents must be viewed in an XPS viewer. Microsoft provides a viewer that allows you to see the document directly in Internet Explorer. Other viewers for other platforms are also being developed. To export the new document that you created in the FlowDocumentReader, you add something that initiates the export process. For this example, add a Button control to the WPF document. The code to do this is presented in Listing 26-11.

Listing 26-11: Adding a Button control to export the document to an XPS document

image from book
      <Window x:          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"          Title="XAML_Example" Height="450" Width="800"          >        <Grid>          <FlowDocumentReader Margin="5,50,5,5" Name="flowDocumentReader1">            <FlowDocument>              <Paragraph>                <Italic>                  <Bold>This is the title of the document</Bold>                </Italic>              </Paragraph>              <Paragraph>                Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent mattis                euismod eros. Aliquam lobortis rhoncus purus ...              </Paragraph>              <Paragraph>                Ut elit lectus, volutpat in, dictum vitae, faucibus vel, nisl. Integer                dictum pede vel lacus. Vestibulum turpis erat, gravida ...              </Paragraph>              <Paragraph>                Pellentesque habitant morbi tristique senectus et netus et malesuada                fames ac turpis egestas. Vivamus iaculis ...              </Paragraph>              <Paragraph>                <Image Source="Sunset.jpg" />                <Italic>This is an image.</Italic>              </Paragraph>            </FlowDocument>          </FlowDocumentReader>          <Button Height="23" HorizontalAlignment="Right" Margin="0,5,5,0" Name="button1"           VerticalAlignment="Top" Width="100" Click="SaveToXPS">Save to XPS</Button>        </Grid>      </Window> 
image from book

As you can see, the Button control is added using the <Button> element, and its location is defined using the Margin attribute. Also notice that the FlowDocumentReader control has changed a bit-its location is altered to make way for the Button control by redefining the Margin attribute. The interesting this about XAML is that the order in which the elements appear in the code is not the order in which they appear in the application. Visually, the button control is at the top of the application now, but it is defined below the <FlowDocumentReader> element within the XAML. This is because everything is positioned using the Margin attributes. This means that these elements can actually appear anywhere you want within the application. The <Button> control on the page should appear as shown in Figure 26-17.

image from book
Figure 26-17

Looking at the code of the <Button> element, you can see a Click attribute as well. This defines the method that should be called in the MyDocument.xaml.cs file when the button is clicked. This is the bit of code which converts the document you created and to an XPS document. This code is presented in Listing 26-12.

Listing 26-12: Saving the document to an XPS file

image from book
      using System.IO;      using System.IO.Packaging;      using System.Windows;      using System.Windows.Documents;      using System.Windows.Xps;      using System.Windows.Xps.Packaging;      namespace XAML_Example      {          public partial class MyDocument : System.Windows.Window          {              public MyDocument()              {                  InitializeComponent();              }              void SaveToXPS(object sender, RoutedEventArgs e)              {                  DocumentPaginator dp =             ((IDocumentPaginatorSource)flowDocumentReader1.Document).DocumentPaginator;                  Package pkg = Package.Open("myDocument.xps", FileMode.Create);                  XpsDocument xpsdoc = new XpsDocument(pkg);                  XpsDocumentWriter xpsWriter =                    XpsDocument.CreateXpsDocumentWriter(xpsdoc);                  xpsWriter.Write(dp);                  xpsdoc.Close();                  pkg.Close();              }          }      } 
image from book

You must import some extra namespaces into the file using statements. These enable you to work with some of the classes that output the contents to an XPS file-such as System.IO.Packaging, System.Windows.Documents, System.Windows.Xps, and System.Windows.Xps, Packaging. The SaveToXPS() method creates a new instance of an XPS document in memory using the XpsDocument object:

      XpsDocument xpsdoc = new XpsDocument(pkg) 

This instance of the XPS document points to an actual XPS document that is to be created from the Package object. This object is passed in as a parameter to the class instantiation. Using the XpsDocumentWriter object, you can write the contents of the flowDocumentReader1 control on your page to the XPS document, which is saved to disk as myDocument.xps.

If you have the Microsoft XPS viewer installed on your machine, you can now open the myDocument.xps file (by double-clicking the file). It automatically opens in this viewer. An example of the document being open in the XPS viewer is presented in Figure 26-18.

image from book
Figure 26-18

As you can see, the new XPS specification provides an easy way to create electronic versions of your documents that appear just as they would on paper. This is quite similar to the PDF model.




Professional XML
Professional XML (Programmer to Programmer)
ISBN: 0471777773
EAN: 2147483647
Year: 2004
Pages: 215

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