Translate

Wednesday, 31 July 2013

How XAML Markup Extensions Works

XAML Markup Extensions

Before we take a look at the results of our data binding, let’s take a moment to discuss
XAML markup extensions, which is what you’re using when you set an attribute
to something inside of curly braces (e.g., Text="{Binding Path=Name}"). Markup
extensions add special processing to XAML attribute values. For example, this:
<TextBox Text="{Binding Path=Name}" />
is just a shortcut for this (which you’ll recognize as the property element syntax):
<TextBox.Text>
<Binding Path="Name" />
</TextBox.Text>


Data Templates


With the data binding markup syntax explained, let’s turn back to our example data
binding application, which so far doesn’t look quite like what we had in mind,It’s clear that the data is making its way into the application, because the currently
selected name and nickname are shown for editing. The problem is that, unlike the
TextBox controls, which were each given a specific field of the Nickname object to show,
the ListBox is expected to show the whole thing. Lacking special instructions, it’s calling
the ToString method of each object, which results in only the name of the type. To
show the data, we need to compose a data template.

Example . Using a data template
<ListBox
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock Text="{Binding Path=Name}" />:
<TextBlock Text="{Binding Path=Nick}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

A data template is a set of elements that should be inserted somewhere. In our case,
we are specifying a data template to be inserted for each listbox item by setting the
ItemTemplate property. In Example, we’ve composed a data template from a text block that flows together two other text blocks, each bound to a property on a
Nickname object separated by a colon, At this point, we’ve got a completely data-bound application. As data in the collection
or the individual objects changes, the UI will be updated, and vice versa. However,
there is a great deal more to say on this topic, including binding to XML and
relational data, master-detail binding, and hierarchical binding.


Dependency Properties



Although our data source Nickname object made its data available via standard .NET
properties, we need something special to support data binding on the target element.
Even though the TextContent property of the TextBlock element is exposed
with a standard property wrapper, in order for it to integrate with WPF services like
data binding, styling, and animation, it also needs to be a dependency property. A
dependency property provides several features not present in .NET properties,
including the ability to inherit its value from a container element, provide for objectindependent
storage (providing a potentially huge memory savings), and change
tracking.
Most of the time, you won’t have to worry about dependency properties versus .NET
properties.

Resources

Resources are named chunks of data defined separately from code and bundled with
your application or component. .NET provides a great deal of support for resources,
a bit of which we already used when we referenced tom.png from our XAML button
earlier in this chapter. WPF also provides special support for resources scoped to elements
defined in the tree.
As an example, let’s declare some default instances of our custom Nickname objects in
XAML 
Notice the Window.Resources, which is property element syntax to set the Resources
property of the Window1 class. Here we can add as many named objects as we like,
with the name coming from the Key attribute and the object coming from the XAML
elements (remember that a XAML element is just a mapping to .NET class names).
In this example, we’re creating a Nicknames collection named names to hold three
Nickname objects, each constructed with the default constructor, and then setting
each of the Name and Nick properties.
Also notice the use of the StaticResource markup extension to reference the names
resource as the collection to use for data binding. With this XAML in place, our window
construction reduces to the code shown in Example 

Example . Declaring objects in XAML
<!-- Window1.xaml -->
<Window ... xmlns:local="clr-namespace:DataBindingDemo" />
<Window.Resources>
<local:Nicknames x:Key="names">
<local:Nickname Name="Don" Nick="Naked" />
<local:Nickname Name="Martin" Nick="Gudge" />
<local:Nickname Name="Tim" Nick="Stinky" />
</local:Nicknames>
</Window.Resources>
<DockPanel DataContext="{StaticResource names}">
<TextBlock DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center">Name: </TextBlock>
<TextBox Text="{Binding Path=Name}" />
<TextBlock VerticalAlignment="Center">Nick: </TextBlock>
<TextBox Text="{Binding Path=Nick}" />
</TextBlock>
...
</DockPanel>
</Window>

Example . Finding a resource in code
public partial class Window1 : Window {
Nicknames names;
public Window1( ) {
InitializeComponent( );
this.addButton.Click += addButton_Click;
// get names collection from resources
this.names = (Nicknames)this.FindResource("names");
// no need to make data available for binding here
//dockPanel.DataContext = this.names;
}
void addButton_Click(object sender, RoutedEventArgs e) {
this.names.Add(new Nickname( ));
}
}

Now instead of creating the collection of names, we can pull it from the resources 
with the FindResource method. Just because this collection was created in XAML 
doesn’t mean that we need to treat it any differently than we treated it before, which 
is why the Add button event handler is the exact same code. Also, there’s no need to 
set the data context on the dock panel because that property was set in the XAML. 
For the full scoop on resources, including resource scoping and lookup, static and 
dynamic binding to resources, and using resources for theming and skinning,


Wednesday, 3 July 2013

How to Edit XAML

Editing XAML

Now that we’ve seen the wonder that is declarative UI description in XAML, you
may wonder, “Do I get all the fun of editing the raw XML, or are there some tools
that can join in the fun, too?” The answer is “sort of.” For example, if you’ve got the
.NET Framework 3.0 extensions for Visual Studio 2005 (the same extensions that give
you the WPF project templates in VS05), you will have a visual editor for XAML files
that works very similarly to the built-in Windows Forms Designer. It will trigger by
default when you double-click a file in the Solution Explorer, or you can right-click on a XAML file in the Solution Expression and choose Open With. One of the options
offered will be “WPF Designer (Cider)” (where “Cider” is the codename for the WPF
Designer still under development). The WPF Designer allows for drag-and-drop-style
construction of XAML files with elements from the Toolbox and setting properties in
the property browser. In addition, you can see the XAML as the designer makes
changes, and in fact, you can make changes in the XAML view itself and see those
reflected in the designer. Figure 1-6 shows the WPF Designer in action.

WPF itself was created as a unified presentation framework, meant to enable building
Windows applications with the best features from existing Windows application
practice and existing web application practice. One of the nice things that web applications
provide is a single window showing the user one page of content/functionality
at a time, allowing for navigation among the pages. For some applications, including
Internet Explorer, the shell Explorer, Microsoft Money, and a bunch of Control Panel
applets, this is thought to be preferable to the more common Windows application
practice of showing more than one window at a time.

To enable more of these kinds of applications, WPF provides the page, which is the
unit of navigation in an XML Browser Application (XBAP). Instead of setting an
application’s StartupUri to a XAML file that defines a window, we point an XBAP’s
StartupUri at a XAML file that defines a page.

Example . Starting with a Page instead of a Window
<!-- App.xaml -->
<Application
x:Class="MyFirstXbapApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Page1.xaml" />

Example . A sample page
<!-- Page1.xaml -->
<Page
x:Class="MyFirstXbapApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowTitle="Page1">
<TextBlock FontSize="36">
Check out <Hyperlink NavigateUri="page2.xaml">page 2</Hyperlink>, too.
</TextBlock>
</Page>
// Page1.xaml.cs
...
namespace MyFirstXbapApp {
public partial class Page1 : System.Windows.Controls.Page {
public Page1( ) {
InitializeComponent( );
}
}
}

The primary way to allow the user to navigate in an XBAP is via the Hyperlink element,
setting the NavigateUri to a relative URL of another XAML page in the project.

As you might imagine, there are many more topics to discuss to make your XBAPs
integrate with the browser and still provide the rich functionality we expect from
WPF applications. In addition, you can have any number of navigation windows in
your standalone WPF applications.


XAML Property Element Syntax

Although setting the Content property as an XML attribute works just fine for specifying
a string as a property, it doesn’t work at all well for specifying a subelement,
like the image example. For this reason, XAML defines the property element syntax,
which uses nested Element.Property elements for specifying objects as property values.
For instance, Example shows the property element syntax for the string setting
of a button’s content.


Example . Property element syntax with a string
<Button Width="100" Height="100">
<Button.Content>Hi</Button.Content>
</Button>


Example . Property element syntax with an image
<Button Width="100" Height="100">
<Button.Content>
<Image Source="tom.png" />
</Button.Content>
</Button>


Example . You can’t have multiple things in a ContentControl
<Button Width="100" Height="100">
<!-- WARNING: doesn't work! -->
<Button.Content>
<TextBlock>Tom: </TextBlock>
<Image Source="tom.png" />
</Button.Content>
</Button>

Sunday, 30 June 2013

What is XAML

XAML

XAML is an XML-based language for creating and initializing .NET objects. It’s used
in WPF as a human-authorable way of describing the UI, although you can use it for
a much larger range of CLR types than just those in WPF. Example 1-8 shows how
we declare the UI of our Window-derived class using XAML.

Example 1-8. Declaring a Window in XAML
<!-- Window1.xaml -->
<Window
x:Class="MyFirstWpfApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Hello, WPF">
<Button
x:Name="button"
Width="200"
Height="25"
Click="button_Click">Click me, baby, one more time!</Button>
</Window>

The root element, Window, is used to declare a portion of a class, the name of which is
contained in the Class attribute from the XAML XML namespace (declared with a
prefix of “x” using the “xmlns” XML namespace syntax). The two XML namespace
declarations pull in two commonly used namespaces for XAML work, the one for
XAML itself (the one with the “x” prefix) and the one for WPF (which we’ve
declared as the default for this XML file). You can think of the XAML


Example . C# equivalent of XAML from Example 1-8 (continued)
void InitializeComponent( ) {
// Initialize Window1
this.Title = "Hello, WPF";
// Initialize button
button = new Button( );
button.Width = 200;
button.Height = 25;
button.Click += button_Click;
this.AddChild(button);
     }
   }
 }

XAML was built to be as direct a mapping from XML to .NET as possible. Generally,
a XAML element is a .NET class name and a XAML attribute is the name of a
property or an event on that class. This makes XAML useful for more than just WPF
classes; pretty much any old .NET class that exposes a default constructor can be initialized
in a XAML file.
Notice that we don’t have the definition of the click event handler in this generated
class. For event handlers and other initializations and helpers, a XAML file is meant
to be matched with a corresponding code-behind file, which is a .NET language code
file that implements behavior in code “behind” the look defined in the XAML. Traditionally,
this file is named with a .xaml.cs extension and contains only the things not
defined in the XAML. With the XAML from Example 1-8 in place, we can reduce
our single-buttoned main window code-behind file to the code in Example 1-10.

Example . C# code-behind file
// Window1.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
namespace MyFirstWpfApp {
public partial class Window1 : Window {
public Window1( ) {
InitializeComponent( );
}
void button_Click(object sender, RoutedEventArgs e) {
MessageBox.Show(...);
  }
 }
}

Notice the partial keyword modifying the Window1 class, which signals to the compiler
that the XAML-generated class is to be paired with this human-generated class to form
one complete class, each depending on the other. The partial Window1 class defined in
XAML depends on the code-behind partial class to call the InitializeComponent
method and to handle the click event. The code-behind class depends on the partial
Window1 class defined in XAML to implement InitializeComponent, thereby providing
the look of the main window (and related child controls).
Further, as mentioned, XAML is not just for visuals. For example, nothing is stopping
us from moving most of the definition of our custom MyApp class into a XAML
file (Example 1-11).

This reduces the MyApp code-behind file to the event handler in Example 1-12.
You may have noticed that we no longer have a Main entry point to create the
instance of the application-derived class and call its Run method. That’s because WPF
has a special project setting to specify the XAML file that defines the application
class, which appears in the msbuild project file.

Example . Declaring an application in XAML
<!-- MyApp.xaml -->
<Application
x:Class="MyFirstWpfApp.MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="AppStartup">
</Application>
Example 1-12. Application code-behind file
// MyApp.xaml.cs
using System;
using System.Windows;
namespace MyFirstWpfApp {
public partial class MyApp : Application {
void AppStartup(object sender, StartupEventArgs e) {
Window window = new Window1( );
window.Show( );
  }
 }
}

Friday, 21 June 2013

Start with WPF

Window Presentation Format (WPF)


WPF is a completely new presentation framework, integrating the capabilities of
many frameworks that have come before it, including User, GDI, GDI+, and HTML,
as well as being heavily influenced by toolkits targeted at the Web, such as Adobe
Flash, and popular Windows applications like Microsoft Word. This chapter will
give you the basics of WPF from scratch, and then a whirlwind tour of the things
you’ll read about in detail in this Blog.

Building Applications In WPF


Building this application (Example 1-2) is a matter of firing off the C# compiler from
a command shell with the appropriate environment variables.* (The command line
here has been spread across multiple lines for readability, but you need to put it all
on one line.)

Example 1. Building a WPF application manually
C:\1st> csc /target:winexe /out:.\1st.exe
/r:System.dll
/r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll"
/r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationCore.dll"
/r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\
PresentationFramework.dll"
MyApp.cs

Here, we’re telling the C# compiler that we’d like to create a Windows application
(instead of a Console application, which we get by default), putting the result, 1st.exe,
into the current folder, referencing the three main WPF assemblies (WindowsBase,
PresentationCore, and PresentationFramework), along with the core .NET System
assembly, and compiling the MyApp.cs source file.
Running the resulting 1st.exe produces the world’s lamest WPF application.

Example 2. A minimal msbuild project file
<!-- 1st.csproj -->
<Project
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>winexe</OutputType>
<OutputPath>.\</OutputPath>
<Assembly>1st.exe</Assembly>
</PropertyGroup>
<ItemGroup>
<Compile Include="MyApp.cs" />
<Reference Include="System" />
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<Import Project="$(MsbuildBinPath)\Microsoft.CSharp.targets" />

</Project>

The msbuild tool is a .NET 2.0 command-line application that understands XML
files in the form shown in Example 2. The file format is shared between msbuild
and Visual Studio 2005 so that you can use the same project files for both commandline
and integrated development environment (IDE) builds. In this .csproj file (which
stands for “C# Project”), we’re saying the same things we said to the C# compiler—
in other words, we’d like a Windows application, we’d like the output to be 1st.exe
in the current folder, and we’d like to reference the System assembly and the main
WPF assemblies while compiling the MyApp.cs file. The actual smarts of how to turn
these minimal settings into a compiled .NET application are contained in the .NET

2.0 Microsoft.CSharp.targets file that’s imported at the bottom of the file.


Example 3. Building using msbuild (continued)
Target CoreCompile:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701
,1702 /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0
\PresentationCore.dll" /reference:"C:\Program Files\Reference Assemblies\Microso
ft\Framework\v3.0\PresentationFramework.dll" /reference:C:\Windows\Microsoft.NET
\Framework\v2.0.50727\System.dll /reference:"C:\Program Files\Reference Assembli
es\Microsoft\Framework\v3.0\WindowsBase.dll" /debug+ /out:obj\Debug\1st.exe /tar
get:winexe MyApp.cs
Target _CopyFilesMarkedCopyLocal:
Copying file from "C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\PresentationCore.dll" to ".\PresentationCore.dll".
Copying file from "C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\System.Printing.dll" to ".\System.Printing.dll".
Copying file from "C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\PresentationCore.xml" to ".\PresentationCore.xml".
Copying file from "C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\System.Printing.xml" to ".\System.Printing.xml".
Target CopyFilesToOutputDirectory:
Copying file from "obj\Debug\1st.exe" to ".\1st.exe".
1st -> C:\1st\1st.exe
Copying file from "obj\Debug\1st.pdb" to ".\1st.pdb".
Build succeeded.
0 Warning(s)
0 Error(s)

Time Elapsed 00:00:04.15

WPF Applications

A real WPF application is going to need more than a message box. WPF applications
have an instance of the Application class from the System.Windows namespace.
The Application class provides methods like Run for starting the application, events
like Startup and SessionEnding for tracking lifetime, and properties like Current,
ShutdownMode, and MainWindow for finding the global application object, choosing
when it shuts down, and getting the application’s main window. Typically, the

Application class serves as a base for custom application-wide data and behavior.