Wednesday, 16 November 2011

WPF Calendar Control

Introduction

Since WPF 4.0, Microsoft provides a full featured calendar control. It provides the following features:

Set the displayed date

The calendar displays by default the current date. But you can specify any other date to be displayed by setting the DisplayDate property.
 
<Calendar DisplayDate="01.01.2010" />
 
 

Selection Modes

The calendar control provides multiple modes for selection. You can set the SelectionMode property to SingleDateSingleRange, MultipleRanges or None.
 
<Calendar SelectionMode="MultipleRange" />
 
 

Blackout dates

The calendar control provides a feature to black out dates that are not valid for selection. You can define multiple ranges by setting the BlackoutDates property to one or multiple CalendarDateRange.
 
<Calendar SelectionMode="{Binding SelectedItem, ElementName=selectionmode}" >
    <Calendar.BlackoutDates>
        <CalendarDateRange Start="01/01/2010" End="01/06/2010" />
        <CalendarDateRange Start="05/01/2010" End="05/03/2010" />
    </Calendar.BlackoutDates>
</Calendar>
 
 

Calendar Modes

The calendar supports three modes to display ranges of dates: Year, Month and Decade. You can control the mode by setting the DisplayMode property.
 
<Calendar DisplayMode="Year" />

WPF PasswordBox Control

The password box control is a special type of TextBox designed to enter passwords. The typed in characters are replaced by asterisks. Since the password box contains a sensible password it does not allow cut, copy, undo and redo commands.
 
<StackPanel>
      <Label Content="Password:" />
      <PasswordBox x:Name="passwordBox" Width="130" />
</StackPanel>
 
 

Change the password character

To replace the asteriks character by another character, set the PasswordChar property to the character you desire.
 
<PasswordBox x:Name="passwordBox" PasswordChar="*" />
 
 

Limit the length of the password

To limit the length of the password a user can enter set the MaxLength property to the amount of characters you allow.
 
<PasswordBox x:Name="passwordBox" MaxLength="8" />
 
 

Databind the Password Property of a WPF PasswordBox

When you try to databind the password property of a PasswordBox you will recognize that you cannot do data binding on it. The reason for this is, that the password property is not backed by a DependencyProperty.
The reason is databinding passwords is not a good design for security reasons and should be avoided. But sometimes this security is not necessary, then it's only cumbersome that you cannot bind to the password property. In this special cases you can take advantage of the following PasswortBoxHelper.
 
<StackPanel>
    <PasswordBox w:PasswordHelper.Attach="True" 
         w:PasswordHelper.Password="{Binding Text, ElementName=plain, Mode=TwoWay}" 
                 Width="130"/>
    <TextBlock Padding="10,0" x:Name="plain" />
</StackPanel>
 
 
The PasswordHelper is attached to the password box by calling the PasswordHelper.Attach property. The attached property PasswordHelper.Password provides a bindable copy of the original password property of the PasswordBox control.
 
public static class PasswordHelper
{
    public static readonly DependencyProperty PasswordProperty =
        DependencyProperty.RegisterAttached("Password",
        typeof(string), typeof(PasswordHelper),
        new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));
 
    public static readonly DependencyProperty AttachProperty =
        DependencyProperty.RegisterAttached("Attach",
        typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, Attach));
 
    private static readonly DependencyProperty IsUpdatingProperty =
       DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), 
       typeof(PasswordHelper));
 
 
    public static void SetAttach(DependencyObject dp, bool value)
    {
        dp.SetValue(AttachProperty, value);
    }
 
    public static bool GetAttach(DependencyObject dp)
    {
        return (bool)dp.GetValue(AttachProperty);
    }
 
    public static string GetPassword(DependencyObject dp)
    {
        return (string)dp.GetValue(PasswordProperty);
    }
 
    public static void SetPassword(DependencyObject dp, string value)
    {
        dp.SetValue(PasswordProperty, value);
    }
 
    private static bool GetIsUpdating(DependencyObject dp)
    {
        return (bool)dp.GetValue(IsUpdatingProperty);
    }
 
    private static void SetIsUpdating(DependencyObject dp, bool value)
    {
        dp.SetValue(IsUpdatingProperty, value);
    }
 
    private static void OnPasswordPropertyChanged(DependencyObject sender,
        DependencyPropertyChangedEventArgs e)
    {
        PasswordBox passwordBox = sender as PasswordBox;
        passwordBox.PasswordChanged -= PasswordChanged;
 
        if (!(bool)GetIsUpdating(passwordBox))
        {
            passwordBox.Password = (string)e.NewValue;
        }
        passwordBox.PasswordChanged += PasswordChanged;
    }
 
    private static void Attach(DependencyObject sender,
        DependencyPropertyChangedEventArgs e)
    {
        PasswordBox passwordBox = sender as PasswordBox;
 
        if (passwordBox == null)
            return;
 
        if ((bool)e.OldValue)
        {
            passwordBox.PasswordChanged -= PasswordChanged;
        }
 
        if ((bool)e.NewValue)
        {
            passwordBox.PasswordChanged += PasswordChanged;
        }
    }
 
    private static void PasswordChanged(object sender, RoutedEventArgs e)
    {
        PasswordBox passwordBox = sender as PasswordBox;
        SetIsUpdating(passwordBox, true);
        SetPassword(passwordBox, passwordBox.Password);
        SetIsUpdating(passwordBox, false);
    }
}
 
 
The Idea for this password helper was originally posted here:
http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html

Tuesday, 15 November 2011

ComboBox with Live Preview


The Live Preview Pattern

If you are using Microsoft Office 2007 or later, you are familiar with the "live preview" concept. They are using it for all kind of selections like color, fonttype or fontsize. The idea behind this pattern is to give the user an immediate feedback, how the object would look like, if he does the selection, without actually doing it. So he can leave the combo and nothing has changed.

How to use the LivePreviewComboBox Control

I encapsulated this functionality into a custom control called LivePreviewComboBox that provides an additional dependency property LivePreviewItem where you can bind to. The following code snipped explains how to use it:
 
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:LivePreviewComboBox">
 
    <StackPanel>
        <TextBlock Text="Preview Value:" />
        <TextBlock Text="{Binding LivePreviewItem, ElementName=liveBox}" />
        <l:LivePreviewComboBox x:Name="liveBox"/>
    </StackPanel>
 
</Window>
 
 

WPF - Third Party Controls

WPF Component Vendors


Data Grids

Charts

Dialogs

Dock

Editors

Effects

GIS and Maps

Multimedia

Misc

Outlook Bar

Panels

Reporting

Ribbon

Toolbar

Theming

Tree

Schedule

3D

Web Browser

How to Create a WPF Custom Control

This article gives you a step by step walktrough how to create a custom control in WPF. If you don't know the differences between a user control and a custom control, I recommend to read the article Custom Control vs. User Control first.

1. Define Requirements

Creating a custom control is quite simple in WPF. But the challenge is to do it the right way. So before you start creating a control try to answer the following questions:

  • What problem should my control solve?
  • Who will use this control? In which context and environment?
  • Can I extend or compose existing controls? Have a look at Existing Controls?
  • Should it be possible to style or template my control?
  • What design-time support should it have? In Expression Blend and Visual Studio?
  • Is it used in a single project, or part of a reusable library?

2. Create Project Structures

Create a new solution in VisualStudio and start with a WPF Custom Control Library and give it the name PopupControlLib. This is the place where our custom control comes in. Next we create an WPF Application and call it PopupControlTest. This is place where we test our control in a simple application.
  1. Create a new solution and start with a WPF Custom Control Library. Call it "PopupControlLib".
  2. Add a second project of type WPF Application to the solution and call it "PopupControlTest".
  3. Add a reference to the custom control library by using the "Add Reference" context menu entry on the "PopupControlTest" project item in the solution explorer.
  4. Rename the CustomControl1 to PopupControl.

3. Choose the right base class

Choosing the right base class is crucial and can save a lot of time! Compare the features of your control with existing controls and start with one that matches close. The following list should give you a good overview from the most leightweight to more heavyweight base types:
  • UIElement - The most lightweight base class to start from. It has support for LIFE - Layout, Input, Focus and Events.
  • FrameworkElement - Derives from UIElement and adds support for styling, tooltips and context menus. It is first base class that takes part in the logical tree and so it supports data binding and resource lookup.
  • Control - is the most common base class for controls (its name speaks for itself). It supports templates and adds some basic properties as Foreground, Background or FontSize.
  • ContentControl - is a control that has an additional Content property. This is often used for simple containers.
  • HeaderedContentControl - is a control that has an Content and a Header property. This is used for controls with a header like Expander, TabControl, GroupBox,...
  • ItemsControl - a control that has an additional Items collection. This is a good choice for controls that display a dynamic list of items without selection.
  • Selector - an ItemsControl whose items can be indexed and selected. This is used for ListBox, ComboBox, ListView, TabControl...
  • RangeBase - is the base class for controls that display a value range like Sliders or ProgressBars. It adds an Value, Minimum and Maximum property.

4. Override the Default Style

Controls in WPF separate behavior and appearance. The behavior is defined in code. The template is defined in XAML. The default template is by convention wrapped into a style that has an implicit key. That is is not a string - as usually - but a Type object of our control.
And that is excactly what we are doing in the static constructor. We are overriding the default value of the DefaultStyleKey property and set it to the Type object of our control.
 
static PopupControl()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(PopupControl),
        new FrameworkPropertyMetadata(typeof(PopupControl)));
}
 
 

5. Create a default Style

The style must be located by convention in a folder called "Themes" that must be located in the root of the control library project. In these folder we can provide different templates for each Windows theme. The name of these ResourceDictionaries must match the name of the windows theme. If we do not provide any theme-specific styles, we need to provide the fallback style located in the "Generic.xaml" file.
As we set the default value of the DefaultStylekey property to the Type object of our control, we must give our default style the same key to be found. This is done by leaving the x:Key attribute out. In this case WPF uses the type object from the TargetType property as key.
 
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Style TargetType="{x:Type local:PopupControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:PopupControl}">
                    ... 
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
 
</ResourceDictionary>
 
 

5. Add DependencyProperties

 
#region DependencyProperty Content
 
/// <summary>
/// Registers a dependency property as backing store for the Content property
/// </summary>
public static readonly DependencyProperty ContentProperty =
    DependencyProperty.Register("Content", typeof(object), typeof(PopupControl),
    new FrameworkPropertyMetadata(null, 
          FrameworkPropertyMetadataOptions.AffectsRender |
          FrameworkPropertyMetadataOptions.AffectsParentMeasure));
 
/// <summary>
/// Gets or sets the Content.
/// </summary>
/// <value>The Content.</value>
public object Content
{
    get { return (object)GetValue(ContentProperty); }
    set { SetValue(ContentProperty, value); }
}
 
#endregion
 
 

6. Map XML Namespace

Content follows...

7. Logical and Visual Children

  • Calling AddLogicalChild() creates the connection to navigate up the logical tree (bubbling).
  • Overriding GetLogicalChildren creates the connection to navigate down the logical tree (tunneling).

The differences between CustomControls and UserControls

WPF has two concepts of controls: UserControls and CustomControls. But what's the difference between them? In this article I try to list the characteristics of each of them to help you to choose the right type for your project.

UserControl (Composition)

  • Composes multiple existing controls into a reusable "group"
  • Consists of a XAML and a code behind file
  • Cannot be styled/templated
  • Derives from UserControl
This example of an "RGB user control" composes three labels and textboxes as well as a color field together to an reusable part. The logic in the code behind file adds a Color DependencyProperty that gets and sets the resolved color.

CustomControl (Extending an existing control)

  • Extends an existing control with additional features
  • Consists of a code file and a default style in Themes/Generic.xaml
  • Can be styled/templated
  • The best approach to build a control library
This example of a "Numeric up/down" control is an extension of a textbox. The up and down buttons are defined in the default template of the control and wired up in the OnApplyTemplate() override in the logic part of the control. The ControlTemplate can easily be exchanged by another that has the up,down buttons aligned left for example.

User Experience Design Process

User Experience becomes a Key Success Factor

In the past, we focused mainly on building products that fulfilled the functional requirements of the user. User experience was often considered late in the development process. But today the customer demands more than just a working product. Providing the right features is still the prerequisite for a good product, but to turn it into something extraordinary you need to provide a good user experience!
Providing a rich user experience is not a thing of fortune. It needs to be planed, designed and integrated into the development of a product. Designing a rich user experience is not only about make up your user interface by some graphics and gradients - its a much broader concept. Its about creating an emotional connection between the user and your software. It makes the user feel good and so he likes to continue using the software.

New Tools for Designers

Microsoft recognized, give development teams the power to create rich user experiences it needs a lot more graphical tool support than VisualStudio can provide today. So they decided to create a new tool suite - made for designers.
This tool suite is called Microsoft Expression. It consists of the four products:
  • Expression Blend is built to create user interfaces in WPF and Silverlight. It builds the bridge between designer and developers. It can open VisualStudio solutions
  • Expression Design is a leightweight version of Adobe Illustrator to create and edit vector graphics.
  • Expression Media is built to encode, cut and enrich video files and optimize them for silverlight streaming
  • Expression Web is Microsoft next generation of HTML and Javascript editor. Its the replacement for Frontpage.
Together they are a powerful package. The following illustration shows a sample workflow of integrating a vector image that is created by a graphics designer in Adobe Illustrator into a WPF project that is part of a VisualStudio solution.

Development Workflow of a WPF Project

Developing a WPF application with a rich user experience requires a lot more skills than just a requirements analyst that defines a list of use cases and developer that implements the software. You have to find out what the user really needs. This can be done by following a user centered approach.

1. Elicit Requirements

Like in any kind of software projects its important to know and focus the target of your development. You should talk to stakeholders and users to find out the real needs. These needs should be refined to features and expressed in use cases (abstract) or user scenarios (illustrative). Priorize the tasks by risk and importance and work iteratively. This work is done by the role of the requirements engineer.

2. Create and Validate UI Prototype

Creating a user interface prototype is an important step to share ideas between users and engineers to create a common understanding of the interaction design. This task is typically done by an interaction designer. It's helpful to only sketch the user interface in a rough way to prevent early discussions about design details. There are multiple techniques and tools to do this. Some of them are:
  • Paper prototype
    Use paper and pencil to draw rough sketches of your user interface. No tools and infrastructure is needed. Everyone can just scribble thier ideas on the paper.
  • Wireframes
    Wireframes are often used to sketch the layout of a page. It's called wireframes because you just draw the outlines of controls and images. This can be done with tools like PowerPoint or Visio
  • Expression Blend 3 - Sketch Flow Sketch flow is a new cool feature to create interactive prototypes directly in WPF. You can use the integrated "wiggly style" to make it look sketchy. The prototype can be run in a standalone player that has an integrated feedback mechanism.
  • Interactive Prototype The most expensive and real approach is to create an (reusable) interactive prototype that works as the real application but with dummy data.
It is strongly recommended to test your UI prototype on real users. This helps you to find out and address design problems early in the development process. The following techniques are very popular to evaluate UI prototypes:
  • Walktrough
    A walktrough is usually done early in a project with wireframes or paper prototypes. The user gets a task to solve and he controlls the prototype by touching on the paper. The test leader than presents a new paper showing the state after the interaction.
  • Usability Lab
    To do a usability lab, you need a computer with a screen capture software and a camera. The proband gets an task to do and the requirements and interaction engineer watch him doing this. They should not talk to him to find out where he gets stuck and why.

3. Implement Business Logic and Raw User Interface

4. Integrate Graphical Design

5. Test software

Roles

Buliding a modern user interface with a rich user experience requires additional skills from your development team. These skills are described as roles that can be distributed among peoples in your development team.

  • Developer
    The developer is responsible to implement the functionality of the application. He creates the data model, implements the business logic and wires all up to a simple view.
  • Graphical Designer
    The graphical designer is responsible to create a graphical concept and build graphical assets like icons,logos, 3D models or color schemes. If the graphical designer is familiar with Microsoft Expression tools he directly creates styles and control templates.
  • Interaction Designer
    The interaction designer is responsible for the content and the flow of a user interface. He creates wireframes or UI sketches to share its ideas with the team or customer. He should validate his work by doing walktroughs or storyboards.
  • Integrator
    The integrator is the artist between the designer and the developer world. He takes the assets of the graphical designer and integrates them into the raw user interface of the developer. This role needs a rare set of skills and so it's often hard to find the right person for it.