VisualStateManager – Execute after Transition Finished

The VisualStateManager (VSM) is a class that allows you to define visual states (think Enabled, Disabled, MouseOver, Deleting, Saving) and programmatically move to those states.  (Part of WPF 4.0, for users of 3.5 you can get it as part of the WPFToolkit)

A great demo and walkthrough of using the VSM is here.

One of the draw backs of using the VSM has been the inability to be notified when the state transition has completed. For instance, say you wanted to animate the removal of an item from a ListBox i.e. some fancy fade and shrinking. You would create a Delete VisualState and when the user deletes you would transition to the Delete state and then remove the item from the list….. or would you?

Animations are kicked off by the VSM and control returned to the calling thread (it’s non-blocking). So in actual fact you will remove the item from the list before the animation really gets going and your databinding will remove the visual item from the ListBox without out all your fancy fade and shrink 😦

Enter PresentVisualStateManager, part of a wider demo (coming soon) of Present Fluent Commands. It allows you to execute an action after the animation has finished, by hooking into the StoryBoard Completed event
Classes are here:

A more MVVM friendly service is in the making but until then a control is passed into ChangeState (ala GotoState and GotoElementState), with the desired state name and an action to perform after the transition completes. ChangeState first calls GoToState (for Visuals defined in ControlTemplates) and if that fails to find the state it calls GoToElementState (for Visuals defined inline)

PresentVisualStateManager.ChangeState(grid, "Delete", () =>  this.itemsCollection.Remove(item.DataContext as ItemViewModel));

TemplateBinding – It’s sugar

When re-templating existing controls the TemplateBinding is your friend. It’s a way of getting user specified values for properties of the control and using them in your control template at runtime.

As in the example below we change a Label into a TextBox and use a TemplateBinding to set the Text of the TextBox to whatever the Content is of the Label.

<Label Content="Show me in a Label">
  <Label.Template>
    <ControlTemplate TargetType="Label">
      <TextBox Text="{TemplateBinding Content}" />
    </ControlTemplate>
  </Label.Template>
</Label>

However, if you try and bind to the Content of the Label you will notice that the source will never get updated with any changes typed into the TextBox/Label.
This is because TemplateBinding is really just syntactic sugar for the following:

{Binding Content, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}

So, if we want to do two-way TemplateBinding we just need to use the following binding instead of using a TemplateBinding.

{Binding Content, RelativeSource={RelativeSource TemplatedParent}}

Inheriting a DefaultStyle

This is mainly for me. I always forget how to do this and when ever I need it I can’t find it!

How do you specify a style for a control but still implement the default style for that control?

Add this line to your style definition (example for a button)

BasedOn="{StaticResource {x:Type Button}}"

WPF Fluent Commands

When writing a Command in WPF there can be a number of behaviours a command may need, to fulfil it’s purpose, which are actually orthogonal to the actual responsibility of the command (let’s say saving). For example the command may need to be scheduled (in the case of Auto-Save), it may need to “busy” the View, be executed asynchronously and ensure the current user has the authorisation to save the current item. Not only that, but the delete command and the load commands may also have to do the same things!

Present‘s Fluent Commands was born to enable the reuse of these common command decorations and allow the composition of commands using a fluent api.  (recently moved to Google Code)

The inner command (Save) is wrapped in a number of decorators each which add a single extra function to the inner command. Present currently has three Command Decorators

  • Schedule Decorator – Repeatedly executes a command every given time period.
  • Requery Decorator – Commands such as Prisms DelegateCommand rely on consumers to raise the CanExecutedChanged event to force the UI to reevaluate the CanExecute value of the command. This is not always feasible. This Decorator wires the CanExecutedChanged event to the CommandManager.RequerySuggested event so the CanExecute method is regularly re-evaluated.
  • Selectable Decorator – A decorator that exposes Properties the UI can use for binding “Selectability”.

More can easily be added, for instance internally we have a security decorator and a maximum concurrent executions decorator.

Scheduled Command

The second addition is Asynchronous behaviour. The AsyncCommand and CompositeAsyncCommand take AsyncActions which describes the life cycle of the operation and are executed using a BackgroundWorker.  The composite command allows for simultaneous asynchronous execution of multiple actions as well as an action to be executed when all actions have completed. Actions can also be decorated with extra behaviour such as the BusyAsyncActionDecorator which busys the View or the ObservableAsyncActionDecorator which turns the action into an Observable.

Async Command

Fluent Commands has now been released as part of Present (recently moved to Google Code).
A sample app can be dowloaded here.

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.

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.

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>

A Temporary Hiatus – XMP

It’s been about 6 months since I left BluFreeway and took to a life of beaches and relaxation that ones honeymoon brings. 🙂

The call of coding had nagged me into installing VS 2008 on our lightweight travel laptop to stay afresh of developments in the .NET space. When a small error on my behalf (no prompts for bulk changes in Vista’s Photo Gallery!!) corrupted all the dates of our wedding photos that Kahlia had painstakingly rated, tagged and categorised.

Smiling smugly i said “No Problem!”, knowing all I had to do was whip up some code to copy the dates from the originals we had backed up. A few minutes later I had some code to do such a task. I even knew about EXIF and how to access it. How proud I was off myself knowing all about this graphics stuff! To my dismay the app whilst changing the metadata did nothing towards fixing the problem in Vista. Apparenlty my knowledge was out of date.

Enter Adobes brain child, XMP, a new era in metadata apparently. Thankfully .NET 3.5 has a great set of classes to handle this, WPF. It made the whole process really simple in the end. If only the documentation was as good.

Know it’s back to the sand and surf for awhile yet.