has a value of #FF8888B7 defines the following resource in Window.Resources with the name
BlueVioletBrushKey:
<SolidColorBrush x:Key="BlueVioletBrushKey">#FF8888B7</SolidColorBrush>
The control will reference this resource as such:
Background="{StaticResource BlueVioletBrushKey}"
You can then apply this resource to other controls using the same means in XAML, or you can
apply it by selecting the control and the property to apply it to, and using the Apply Resource option
on the property marker menu described previously.
The WPf Designer and XaMl editor .
367
In the designer you will find that (as with Windows Forms)
double-clicking a control automatically creates an event
handler for that control’s default event in the code-behind.
You can also create event handlers for any of the control’s
events using the Properties window as you would in
Windows Forms. Clicking the lightning icon in the Properties
window takes you to the Events view, as shown in
Figure 18-16. This shows a list of events that the control
can raise, and you can double-click the event to
automatically create the appropriate event handler in the
code - behind.
fiGure 18-16
For VB.NET developers, double-clicking the Button control or creating the
event via the Properties window wires up the event using the Handles syntax.
Therefore, the event handler is not assigned to the event as an attribute.
If you use this method to handle the event you won’t see the event handler
defined in the XAML for the control, and thus you won’t be able to use the
Navigate to Event Handler menu (from Figure 18-6) when in the XAML editor
to navigate to it.
data binding features
Data binding is a very important concept in WPF, and is one of its core strengths. Data binding
syntax can be a bit confusing initially, but Visual Studio 2010 makes creating data bound forms
very easy in the designer. Visual Studio 2010 helps with data binding in two ways: with the Apply
Data Binding option on a property in the Properties tool window, and the drag and drop data
binding support from the Data Sources window. This section looks at these two options in turn.
In WPF you can bind to objects (which also includes datasets, ADO.NET Entity Framework
entities, and so on), resources, and even properties on other controls. So there are very rich binding
capabilities in WPF and you can bind a property
to almost anything you want to. Hand-coding
these complex binding expressions in XAML can
be quite daunting, but the Apply Data Binding
editor enables you to build these expressions via
a point-and-click interface.
To bind a property on a control first select the
control in the designer and find the property you
want to bind in the Properties window. Click the
property marker icon and select the Apply Data
Binding option. Figure 18-17 shows the window
fiGure 18-17
that appears.
368 .
chaPter 18 WindoWS preSenTATion FoundATion (WpF)
This window contains a number of steps (similar to a wizard) that help you create a binding -
Source, Path, Converter, and Options in an accordion style layout. Click on a header to open the
corresponding step.
Generally when you open the window, you will be presented with the Source step that will
allow you to select the binding source (in other words, the source of the data to which you
will be binding). Note that this step may be automatically skipped and show the Path selection
step instead (as shown in Figure 18-18) if there is already a data context set on the control
(or further up the hierarchy). If you want to use one of the other types of bindings (such as
ElementName), simply select the header of the Source step to change the preselected binding
source. Then you can follow through selecting the options for your binding (select an option
then move onto the next pane).
In the example shown in Figure 18-17, you have a Grid control further up the hierarchy to which
has been assigned a CollectionViewSource resource (which points to a ViewModel object as the data
source) to its DataContext property. The DataContext property’s value is inherited by the controls
further down the hierarchy, so when applying a data binding to a text box within that grid you
can specify that the binding source is the text box’s DataContext property (which is shown as
having a List assigned to it). Once you have
selected your binding source, you can move on
to the Path step.
The Path step enables you to select the path
on the binding source from which the value
to be bound is located. For example, in
Figure 18-18 the Company property (which is
on the ViewModel that the binding source is
bound to) has been selected.
If that property itself is an object, you can
drill down and select the property on that to
bind to (and so on). As can be seen in
Figure 18-18, the company property (a string)
has a Length property that we could bind to if
we wished.
Double-click your final selection in your
binding to close the editor. If required you
can select a converter to use (see Figure 18-19)
that will transform the bound value before
assigning it to the selected property, and
transform it again before a value is set back on
the bound property (a very powerful feature in
WPF data binding).
fiGure 18-18
fiGure 18-19
The WPf Designer and XaMl editor .
369
Various other binding options can also be set
from the Options section as shown in
Figure 18 - 20.
As you can see, this binding expression builder
makes creating the binding expression much
easier, without requiring you to learn the data
binding syntax. This is a good way to learn the
data binding syntax, because you can then see
the expression produced in the XAML.
Now look at the drag and drop data binding
features of Visual Studio 2010. The fi rst step is
to create something to bind to. This can be an object, a dataset, or an ADO.NET Entity Framework
entity, among many other binding targets. For the purposes of this example you will create an object
to bind to. Create a new class in your project called ContactViewModel, and create a number of
properties on it such as FirstName, LastName, Company, Phone, Fax, Mobile, and Email (all strings).
fiGure 18-20
The name of your object is called ContactViewModel because it is acting as your
ViewModel object, which pertains to the Model-View-ViewModel (MVVM) design
pattern mentioned earlier. This design pattern will not be fully fleshed out in this
example, however, in order to reduce its complexity and save potential confusion.
Now compile your project (this is important or otherwise the class won’t
appear in the next step). Return to the designer of your form and select
Add New Data Source from the Data menu. Select Object as your data
source type, click Next, and select the ContactViewModel class from the
tree (you will need to expand the nodes to find it within the namespace
hierarchy). Click the Finish button and the Data Sources tool window
appears with the ContactViewModel object listed and its properties below,
as shown in Figure 18-21. fiGure 18-21
Now you are set to drag and drop either the whole object or individual
properties onto the form, which will create one or more controls to
display its data. By default a DataGrid control will be created to display
the data, but if you select the ContactViewModel item, it will show a
button that when clicked displays a drop-down menu (as shown in
Figure 18-22) allowing you to select between DataGrid, List,
fiGure 18-22
and Details.
.
The DataGrid option creates a DataGrid control, which has a column for each property of
the object.
.
The List option creates a List control with a data template containing fields for each of the
properties.
370 .
chaPter 18 WindoWS preSenTATion FoundATion (WpF)
.
The Details option creates a Grid control with two columns: one for labels and one for
fields. A row will be created for each property on the object, with a Label control displaying
the field name (with spaces intelligently inserted before capital letters) in the first column,
and a field (whose type depends on the data type of the property) in the second column.
A resource is created in the Resources property of the Window, which points to the
ContactViewModel object that can then be used as the data context or items source of the control(s)
binding to the object. This can be deleted at a later stage if you want to set the data source from the
code-behind. The control(s) will also have the required data binding expressions assigned. The type
of control(s) that will be created on the form to display the data will depend
on your selection on the ContactViewModel item.
The type of control created for each property will have a default based upon
the data type of the property, but like the ContactViewModel item you can
select the property to show a button that when clicked displays a drop-down
menu allowing you to select a different control type (as shown in
Figure 18-23). If the type of control isn’t in the list (such as if you want to
use a third-party control), you can use the Customize option to add it to the
list for the corresponding data type. If you don’t want a field created for that
property, select None from the menu.
For this example you will create a details form, so select Details on
the ContactViewModel item in the Data Sources window. You can
change the control generated for each property if you want, but for
now leave each as a textbox and have each property generated in the
details form. Now select the ContactViewModel item from the Data
Sources window and drop it onto your form. A grid will be created
along with a field for each property as shown in Figure 18-24.
Unfortunately there is no way in the Data Sources window to define
the order of the fields in the form, so you will need to reorder the
controls in the grid manually (either via the designer or by modifying
the XAML directly).
When you look at the XAML generated you will see that this drag
and drop data binding feature will save you a lot of work and make the process of generating forms
a lot faster and easier.
fiGure 18-23
fiGure 18-24
If you write user/custom controls that expose properties that may be assigned
a data binding expression you will need to make these dependency properties.
Dependency properties are a special WPF/Silverlight concept whose value can
accept an expression that needs to be resolved (such as data binding expression).
Dependency properties need to be defined differently than standard properties.
The discussion of these is beyond the scope of this chapter, but essentially only
properties that have been defined as dependency properties can be assigned a
data binding expression.
styling Your application .
371
stylinG your aPPlication
Up until now, your application has looked very plain — in fact it could be considered much plainer
than if you had designed it in Windows Forms. The great thing about WPF, however, is that the
visual appearance of the controls is easy to modify, allowing you to completely change the way
they look. You can store commonly used changes to specific controls as styles (a collection of
property values for a control which is stored as a resource that can be defined once and applied
to multiple controls), or you can completely redefine the XAML for a control by creating a new
control template for it. These resources can be defined in the Resources property of any control in
your layout along with a key, which can then be used by any controls further down the hierarchy
that refer to it by that key. For example, if you wanted to define a resource available for use by
any control within your MainWindow XAML file you could define it in Window.Resources.
Or if you wanted to be able to use it throughout the entire application you could define it in the
Application.Resources property on the Application element in App.xaml.
Taking it one step further, you could define multiple control templates/styles in a resource dictionary
and use this as a theme. This theme could be applied across your application to automatically style
the controls in your user interface and provide a unique and consistent look for your application.
This is what this section looks at. Rather than creating your own themes you will actually be
using the themes available from the WPF Themes project on CodePlex: http://www.codeplex
.com/wpfthemes.
These themes were initially designed (most by Microsoft) for use
in Silverlight applications, but have been converted (where it was
necessary) so they can be used in WPF applications. Use one of these
themes to create a completely different look for your application.
Start by creating a new application and adding some different
controls on the form, as shown in Figure 18-25.
As you can see this looks fairly bland, so try applying a theme and
seeing how you can easily change its look completely. When you
download the WPF Themes project you will see that it contains a solution with two projects: one
providing the themes, and a demonstration project that uses them. You will use the themes slightly
differently, however. Run the sample application and find a theme that you like. For the purposes of
demonstration choose the Shiny Blue theme. In the WPF.Themes project under the ShinyBlue folder
you will find a Theme.xaml file. Copy this into the root of your own project (making sure to include
it in your project in Visual Studio).
Open up App.xaml and add the following XAML code to Application.Resources:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Theme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
This XAML code simply merges the resources from the theme file into your application resources,