MVVM Animation of ListBox – Present.Commands

Using the Present.Command decorator to change visual states after a command execution we can easily animate the addition and deletion of items in a WPF ListBox in an MVVM friendly way.
(The code is in svn for the async command samples)

Firstly, our ViewModel’s: we have an ItemViewModel representing an item in the ListBox; and an ItemCollectionViewModel representing our ListBox. Our ItemCollectionViewModel contains the two commands we are primarily focused on, Add and Delete.

AddCommand

  AddCommand = Command.Async
               (
  AsyncAction.FromDelegatesItemViewModel>()
                       .Do(x => new ItemViewModel("New Item "))
  .OnSuccess(Add)
  .ToAction()
  .SuccessVisualState(ItemVisualStates.Add)
  ).ToCommand();

Pretty self-explanatory, we create a new item, Add it to the collection and change the state of the new item viewmodel to “Add”

DeleteCommand

DeleteCommand = Command.Async
                (
                    AsyncAction.FromDelegates<ItemViewModel, ItemViewModel>()
                        .Do(e =>
                                {
                                    e.Parameter.IsDeleting = true;
                                    Thread.Sleep(2000);
                                    return e.Parameter;
                                })
  .ToAction()
  .SuccessVisualState(ItemVisualStates.Delete, item => Remove(item))
  ).ToCommand();

The delete command is a little more involved. We set the Parameter (the item to delete) to “deleting” and sleep to simulate server call. Once we have deleted it on the server we play the delete animation (by changing the visual state to delete) and then once everything is finished we remove the item from the collection.

ListBox Item DataTemplate

 <DataTemplate>
          <!--Register the View, so it is acessible from Services, bind the current visual state so the ViewModel can control it-->
          <UniformGrid Name="grid" Style="{StaticResource DemoGrid}"  VerticalAlignment="Center" Commands:PresentVisualStateManager.GoToState="{Binding State}"
                       Core:ViewRegistry.Register="true">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="ActionStates">
                <VisualState x:Name="Add"  Storyboard="{StaticResource AddAnimation}"/>
                <VisualState x:Name="Delete"  Storyboard="{StaticResource DeleteAnimation}"/>
              </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>

            <Button Command="{Binding DataContext.DeleteCommand, ElementName=List}" CommandParameter="{Binding}" Height="20" Width="20">
              <Button.Style>
                <Style TargetType="Button" BasedOn="{StaticResource ImageButton}">
                  <Style.Triggers>
                    <DataTrigger Binding="{Binding IsDeleting}" Value="True">
                      <Setter Property="Content">
                        <Setter.Value>
                          <Viewbox Width="{TemplateBinding Button.Width}" Height="{TemplateBinding Button.Height}">
                            <Progress:CircularProgressBar />
                          </Viewbox>
                        </Setter.Value>
                      </Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding IsDeleting}" Value="False">
                      <Setter Property="Content">
                        <Setter.Value>
                          <Image Source="{StaticResource imgMediumCross}"
                                 Width="{TemplateBinding Button.Width}"
                                 Height="{TemplateBinding Button.Height}" />
                        </Setter.Value>
                      </Setter>
                    </DataTrigger>
                  </Style.Triggers>
                </Style>
              </Button.Style>
            </Button>

              <Label Content="{Binding Name}" />

          </UniformGrid>

        </DataTemplate>

Here we define the VisualStates Add and Delete and their corresponding animations (static resources)
We change the Button image to a circular progress bar whilst we are deleting.
We register the View with the ViewRegistry and bind to the delete command.
With a little more designer input we have a beautiful animating listbox ;)

About these ads
Tagged , , , , , ,

5 thoughts on “MVVM Animation of ListBox – Present.Commands

  1. [...] This post was mentioned on Twitter by André Alves de Lima, Janny Gomes. Janny Gomes said: MVVM Animation of ListBox – Present.Commands http://bit.ly/g4ZbCP [...]

  2. John Staines says:

    This looks great but unfortunately I’m not nearly clever enough to work out how to use it. Can you help me out a bit please because I’d love to be able to use this framework. So far, I’ve copied down everything from /trunk/Commands/Sample into a new project and added the required references after picking up the libraries from elsewhere in the google code.
    Right, now I get the following errors;

    ‘Present.Commands.Async.Actions.IAsyncAction’ does not contain a definition for ‘SuccessVisualState’ and no extension method ‘SuccessVisualState’ accepting a first argument of type ‘Present.Commands.Async.Actions.IAsyncAction’ could be found (are you missing a using directive or an assembly reference?)

    and another along the same lines for the Add command and I also get errors in the view;

    The attachable property ‘GoToState’ was not found in type ‘PresentVisualStateManager’.

    and

    The attachable property ‘Register’ was not found in type ‘ViewRegistry’.

    Could you please kindly give me some pointers as to what I’m doing wrong?

    • adammills says:

      Without seeing your code it could be a lot of things.
      The SuccessVisualState is an extension method in Present.Commands.Async.Actions namespace of Present.Commands.dll.
      Make sure you are using .NET 4.0 in your build settings and not 3.5 or client profile.
      There is also an older VisualStateManager that is in the Wpf Toolkit. Make sure the one being used is the one from the WPF 4.0 PresentationFramework.dll (a system library)

  3. John Staines says:

    hi adam,

    Thanks for your quick response and sorry for the delay in replying (I rather sillilly relied on hotmail to tell me when a res
    ponse came in to my question. Ok, so I’ve checked the versions of my references and all seem to be version 4.0 (runtime version v4.0.30319 to be exact)
    and when I navigate to the Present.Commands.Async.Actions namespace there is no SuccessVisualState there. I was wondering actually if you were able to send me a zip file
    of the sample code for the listbox in your video?

    • adammills says:

      My apologies, I had been looking at an older svn repository. I hadn’t realized my migration to nuget in the new Mercurial repository was not finished. It is now and all compiles.
      I will also send you source.

      Thanks
      Adam

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 28 other followers

%d bloggers like this: