Simple Empty Template for ItemsControls

One of my favourite elements in WPF is the VisualBrush. It allows you to define content (i.e. XAML) and then use it where ever you can use a brush.

Using this brush we can easily define content for an ItemsControl when it has no items.
We set a datatrigger to watch the Items.Count and when it’s zero make the background whatever content you want. In this example I just whack in some text.
As such:

<ListBox Height="100" Width="100"   ItemsSource="{Binding ItemsToBind">
  <ListBox.Style>
    <Style TargetType="ListBox" >
      <Style.Triggers>
        <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" 
                     Value="0">
          <Setter Property="Background">
            <Setter.Value>
              <VisualBrush Stretch="None">
                <VisualBrush.Visual>
                   <TextBlock Text="No Items" />
                </VisualBrush.Visual>
              </VisualBrush>
            </Setter.Value>
          </Setter>
        </DataTrigger>
      </Style.Triggers>					
    </Style>
  </ListBox.Style>
</ListBox>

PopUp Dialog Behaviour

Based on the StaffLynx application’s modal control-based popups and inspired by this post by Brad, I set about creating a PopUp Dialog Blend Behaviour and sample which I have put into the Expression Gallery.

Sample

The behaviour allows for Dialogs to be easily added to a WPF application. If the dialog is Modal, it is modal to any part of the window (not just the whole window) i.e. a Tab. This allows for non-linear application navigation as the entire window is not locked down.

The behaviour is applied to any grid (other panels aren’t supported at the moment), if it is modal this will be the area that is disabled when the dialog appears. The showing and hiding of the dialog is controlled by the Visible dependency property on the behaviour, and the modal drum skins color and opacity can be set. There is currently no support for animation, but could easily be added (please send in the changes if you do 🙂 )

The dialog is any UiElement as in this sample is a usercontrol (line 5).

Behavior XAML from the Sample

<Grid Grid.Row="1">
      <e:Interaction.Behaviors>
        <ch:PopUpBehaviour x:Name="SampleDialog" Modal="true" Visible="{Binding ElementName=Go, Path=IsChecked, Mode=TwoWay}">
          <ch:PopUpBehaviour.PopUp>
            <Sample:Dialog />
          </ch:PopUpBehaviour.PopUp>
          <ch:PopUpBehaviour.ModalBehaviour>
            <ch:DisableBackGroundBehaviour Background="Pink" />
          </ch:PopUpBehaviour.ModalBehaviour>
        </ch:PopUpBehaviour>
      </e:Interaction.Behaviors>

The main reason I started looking into alternatives to Brad’s solution was a better separation of visuals and behaviour, primarily ease of styling of the actual dialog.  It also puts any behaviour requirements in the hands of the dialog designer. If you want dragability or resiziability you have to implement it, thankfully it’s as easy as adding other blend behaviours. The below code snippet is the contents of a sample dialog, it can be any UiElement .

Dialog XAML from the Sample

 <Border BorderThickness="1" Background="BlanchedAlmond"  Width="150" Height="150">
    <e:Interaction.Behaviors>
      <il:MouseDragElementBehavior ConstrainToParentBounds="True"/>
    </e:Interaction.Behaviors>
    <dropShadow:SystemDropShadowChrome>
      <DockPanel Background="White" Opacity="1" Margin="1">
        <UniformGrid DockPanel.Dock="Bottom">
          <Button Command="ApplicationCommands.Close" Width="50">Close</Button>
        </UniformGrid>
        <TextBlock DockPanel.Dock="Top" Text="Dialog" />
      </DockPanel>
    </dropShadow:SystemDropShadowChrome>
  </Border>

To Close the dialog you can either set the behaviour Visible property to false or execute the ApplicationCommands.Close command as per the sample. (Line 8 in the dialog)

A more MVVM oriented Dialog Service based on this behaviour will soon be released in Present.

Single Responsibility Misuse

The Inquisitive Coder recently made a post about MVVM being overrated. He states a preference for MVP (a great pattern, and a great implementation of it for WPF is Caliburn). Whilst patterns are there to be abused used as the needs of a project dictate. I think the arguments are subject to a common flaw in peoples thinking, especially around front-end patterns.

The primary attack on MVVM is that it violates the Single Responsibility Pattern (SRP). In short SRP states that a class should have one and only one reason to change. David suggests that ViewModels have 2 reasons to change (paraphrased)

  1. If, the Model changes
  2. If, the View requirements change ( i.e. needs more model data displayed/edited)

This is not what I take issue with, it’s true. But it’s true of all bridge classes and interfaces; DTO’s, Data Layers and UI’s. A bridge depends on both sides, but that is it’s responsibility. Sometimes the SRP is looked at from a much to granular view point and it leads to anaemic domains. People want to separate data from behaviour it seems to be human nature. I regularly hear SRP as the reason why this is good.

From Daniels post the 2 responsibilities a ViewModel has are:

  • communication/interaction with the Model
  • making data (from the Model) available so it can be displayed

Rephrased

  • Behaviour
  • Data

The SOLID principles (of which the S stands for SRP) are a great way to evaluate code and patterns, but they take a back seat to the tenets of OO Design

  • encapsulation
  • inheritance (I think this should be renamed Inheritance and Composition or removed as being implicit in polymorphism)
  •  polymorphism

Encapsulation states thou shall not whore out your data to other classes. Whilst UI is a grey area for encapsulation as we all need to display our data. MVVM takes a step closer to encapsulation by keeping the behaviour and data together.

In my opinion ViewModels contain their data and the behaviour that relies on it in one place with the single responsibility of Modelling a View.  If your ViewModels are two big or unwieldy then look at decomposing them into self contained Commands (with both data and behaviour) and/or smaller ViewModels with clearer responsibilities (an upcoming post).

Side Note
After 18 months of MVVM I too am starting to wonder if the extra work required to maintain two-way synchronization (View-Model) is worth it for most scenarios. But that’s another topic and to do with choosing the right tool for the job. I still believe MVVM is the most elegant pattern for solving the problem it solves.

MVVM Validation and Type Checking

This post is based on Present.Validation a part of the Present project at codeplex.

ScreenShot

Present.Validation is an implementation of IDataErrorInfo for MVVM which uses a pluggable contributor pattern to provide validation. It currently has a single contributor for use with System.ComponentModel.DataAnnotations. Validation can then be acheived by decorating the ViewModel properties with attributes

 [Range(0, 120, ErrorMessage = "Age must be between 0 and 120")]
public int Age 
 <StackPanel>
        <v:BrokenBindingNotifier PropertiesWithBrokenBindings="{Binding Validator.BrokenBindings}" />
        <Controls:Form Padding="20">
            <TextBox Controls:FormItem.LabelContent="_Firstname" Text="{v:ValidatedBinding FirstName}" />
            <TextBox Controls:FormItem.LabelContent="_Lastname" Text="{v:ValidatedBinding LastName}" />
            <TextBox Controls:FormItem.LabelContent="_Age" Text="{v:ValidatedBinding Age, TargetNullValue={x:Static System:String.Empty}}" />
        </Controls:Form>
        <Button Content="Save" Command="{Binding SaveCommand}" Width="50"/>
    </StackPanel>

There are plenty examples of implementing IDataErrorInfo on the web, but they tend to ignore broken bindings. Broken Bindings occur for a number of reasons such as the binding source can’t be found or the Path is invalid. They also occur when the input value can’t be coerced back to the data type of the source.

For example if someone tries to enter Twelve into a text box bound to the int Age property the binding will break; leaving the value of Age unset and the ViewModel unaware of the error.

Present.Validation tackles this via a binding notifier which binds broken bindings to the a validator. (Line 2 of the Xaml). It also uses a custom binding ValidatedBinding which just sets all the needed error checking properties to true.

Gotcha: Nullable Types

Watch out when using nullable types that you set the TargetNullValue as for the Age binding. An empty textbox is set to String.Empty which isn’t compatible with int?. So we need to tell WPF that String.Empty is equal to Null.

Binding Syntax – Attached Properties

CommandParameter="{Binding
Path=(Grid:GridPopupMenu.GridMenuInfo).Menu.(Dx:GridViewBehaviours.MenuRowData),
RelativeSource={RelativeSource Self}}"

Working with a Third-Party library that isn’t necessarily designed with MVVM in mind 😉 I often need to play around with Attached Properties to achieve the desired result. One of the great things with WPF bindings is that you can combine any of the supported notations into a large chain (as above).

The properties wrapped in () are attached properties, the first is being applied to the control in question (due to RelativeSource=Self), the second is being applied to the Menu control.

Amazing WPF LOB App

image_2

A little late to the game, I have only just encountered the StaffLynx demo. It’s a movie demo of an application created by Billy Hollis. An amazing example of application design and what can be done when you mix designers and devs. It’s non-linear flow is awesome!

There is also some amazing info about UI design and interaction in his Tech-Ed 2009 slides about the demo.

Window.Close() from XAML

It’s been a long time since I last posted. Since then I have been working on my first WPF contract. I have definately drank the cool aid, I love WPF (when MVVM is being used anyway).

One thing I haven’t been able to find any info on is how to close a window or dialog from XAML. I tried and tried and then gave up. Until now!

Having discovered the power of Attached Behaviours, I decided to write one that would close a window. All you need do then is create a data trigger that watches a CloseSignal on the ViewModel and sets the Close property to true.

public static class WindowCloseBehaviour
{
public static void SetClose(DependencyObject target, bool value)
{
target.SetValue(CloseProperty, value);
}
public static readonly DependencyProperty CloseProperty =
DependencyProperty.RegisterAttached(
"Close",
typeof(bool),
typeof(WindowCloseBehaviour),
new UIPropertyMetadata(false, OnClose));
private static void OnClose(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is bool && ((bool)e.NewValue))
{
Window window = GetWindow(sender);
if (window != null)
window.Close();
}
}
private static Window GetWindow(DependencyObject sender)
{
Window window = null;
if (sender is Window)
window = (Window)sender;
if (window == null)
window = Window.GetWindow(sender);
return window;
}
}

and then in your XAML

<Style.Triggers>
   <DataTrigger Binding="{Binding CloseSignal}" Value="true">
        <Setter Property="Behaviours:WindowCloseBehaviour.Close" Value="true" />
   </DataTrigger>
</Style>