Category Archives: WPF

Sadly True: No Good Options for LOB Windows Apps

Sadly True: No Good Options for LOB Windows Apps

Advertisements
Tagged , , ,

INotifyOnChange Performance Issues

Intresting article here; that profiles the performance of doing change notification varying ways. Notably the typical Lambda method of change notification is 3-20 times slower than string based notifications.

Lambdas have some value outside performance that must be weighed, but if your app is sluggish and uses a lot of bindings; something to consider.

Vote for WPF’s Future

Came across this, http://dotnet.uservoice.com/forums/40583-wpf-feature-suggestions

You can vote for the things the WPF team should focus on.

WPF Memory Leak By Design

I have just finished debugging a memory leak in our code base. The culprit was a global static command which was rooting all controls ever attached to it, through its CanExecuteChanged event.

Surely controls which attach to this event, detach!?

No. WPF expects the ICommand.CanExecuteChanged event to apply WeakReferences for EventHandlers.
So beware if you use global commands that don’t implement this correctly.

An example of how to implement this is here.

http://www.codeproject.com/KB/WPF/NitoMVVMCommands.aspx

MVVM uses for ApplicationCommands.Close

ApplicationCommands.Close is an example of a RoutedCommand (it’s actually a descendant RoutedUICommand). RoutedCommands are a special case in WPF which when executed fire a RoutedEvent which can then be handled up the in the Visual Tree. It’s a special case becase it doesn’t follow the ICommand interface; for it to work it requires Execute and CanExecute to take an extra parameter: CommandTarget.

In order to get this extra parameter it must be bound to an ICommandSource, such as a button which knowns to pass in an IInputElement into Execute and CanExecute. This makes using it in MVVM a little difficult as we would need a View element in our ViewModels.

People often think about using ApplicationCommands.Close with MVVM and Dialogs. It would be nice to bind a CompositeCommand to a Save button for example; the first command saves the second command being the ApplicationCommands.Close would trigger the dialog to close. Unfortunately there is no CompositeCommand that supports RoutedCommands and I’m not sure the concept of RoutedCommands supports the Composite Pattern (there is a possiblility here to investigate).

There are still uses for ApplicationCommands.Close in MVVM however.
If like PopUpBehaviour, your dialogs use an ApplicationCommands.Close  CommandBinding to close the Window or PopUp, binding a Close Button to ApplicationCommands.Close is an easy way to close the dialog.

In Part 2 I’ll look at how to use ApplicationCommands.Close as the signal for closing Dialogs/Windows.

Tagged , , , ,

EventToCommand Action – MVVM Glue

One of my favourite additions to WPF is the Blend Interactivity library which allows you to decorate behaviour into controls in XAML. This really is the glue that allows you to work around MVVM problems in third-party libraries or the framework itself.

The following is an example of a Trigger and Action, to bind SelectedItems to a ViewModel as it changes. This work around is required as SelectedItems isn’t bindable.

<ListBox Name="ItemsToChoose">
  <i:Interaction.Triggers>
    <!-- Can't bind directly to Selected Items 😦 -->
    <i:EventTrigger EventName="SelectionChanged">
      <Command:ChangePropertyOnTarget
          Target="{Binding}" PropertyName="SelectedItems"
          Value="{Binding SelectedItems, ElementName=ItemsToChoose}" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListBox

One of the most common scenarios for me is the need to execute a command when a control raises a particular event. For instance double-clicking an item in a ListView. The MVVM Light Toolkit has  a great TriggerAction called EventToCommand which has been a great help, allowing me to redirect an event and turn it into a command as such:

<ListBox Name="list">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseDoubleClick">
      <Command:EventToCommand
           Command="{Binding Path=DataContext.DoSomethingCommand,ElementName=list}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListBox>

There are two small short-comings with the original. Firstly that it provides no access to the EventArgs. I have tweaked the original to add an EventArgs which you can use in your bindings of the command parameter. (Source Here)

This example shows the tweaked EventToCommand, passing in the DataContext of the clicked row.

<ListBox Name="list">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseDoubleClick">
      <Command:EventToCommand
           Command="{Binding Path=DataContext.DoSomethingCommand,ElementName=list}"
 CommandParameter="{Binding EventArgs.OriginalSource.DataContext, RelativeSource={RelativeSource Self}}"/>
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListBox>

I have also rectified the second issue; it doesn’t implement ICommandSource so it does not handle RoutedCommands.

Tagged , , ,

Requery Not Suggested

During my first WPF project I noticed (like most people starting in WPF do) that DelegateCommand.CanExecute is called once and never refreshed. To force a refresh one must call RaiseCanExecuteChanged when the state of CanExecute has changed. That had a few smells about it and was cubersome, so when I stumbled across CommandManager.RequerySuggested I thought all my problems were solved.

From MSDN ”Occurs when the CommandManager detects conditions that might change the ability of a command to execute.”

All I did was create my own DelegateCommand and proxy the CanExecutedChanged event to the CommandManager.RequerySuggested event and every time WPF noticed something change it would force a refresh of my CanExecute methods. I even had the audacticity to call it BetterDelegateCommand!!

This didn’t cause too many problems on the project, as a general rule people know to keep the CanExecute logic quick and we had linear navigation in the application so there wouldn’t have been more than 10 commands bound at anyone point.

Things quickly change when you move to apps that have multiple windows/dialogs/plugins loaded and hundreds of commands can be bound. Spice that up with a developer adding CanExecute methods that do a little more than test the value of a variable and you get a significant slowdown which is very hard to debug.

Because there are times when using the RequerySuggested method is preferable Present.Commands provides the RequeryCommandDecorator and fluent method.

MyCommand = Command.Async(new SomeAction())
                   .ToCommand()
                   .SuggestRequery();

For everything else there is the CanExecuteChangedDecorator and fluent command. It allows you to specify an Observable which it subscribes to, when a notification comes through the CanExecuteChanged event is fired. Using an Observable adds a powerful filtering and joing tool to define when the command ‘s state has changed.

  MyCommand = Command.Async(new SomeAction())
                                .ToCommand()
                                .CanExecuteChangedWhen(this.WhenPropertyChanges(x => x.SomeProperty));
Tagged , , , ,

Everything needs a ViewModel – CollectionViewModel

CollectionViewModelThe title is a little misleading; but everyone loves generalisations and WPF. 😉
It may have been better named view-first decomposition or something similarly benign.

One of the big issues people face when implementing MVVM is collections (example, example), primarily how do I keep my model in sync. 

The reason; IMO, is that people tend to compose their ViewModels based on the models they are trying to display on-screen. Whilst this is not a bad idea (mainly because screens tend to be modelled on the models as well 🙂 ) solutions often come from a design-first approach whereby your ViewModels represent parts of the screen (not necessarily parts of the model or only a single model).

As an example take a Customer who has a collection of Addresses. When we create ViewModels based on the Model we tend to only see our objects i.e. Customer and Address. When we see a collection the first reaction is whack in a ObservableCollection.

 When creating the view that contains a collection it will often be displayed as some type of ItemsControl. The ItemsControl will often contain buttons for Adding, Deleting, Moving etc. When we look at it from the perspective of screen decomposition it becomes much clearer that there is some list component there which needs a ViewModel.

Once we come to this realisation the CollectionViewModel becomes self-evident. It’s responsibility is to maintain the underlying model; when a ViewModel is deleted from the collection it deletes the corresponding model from the underlying collection, same for add and move. I do this by listening to CollectionChanged event and providing the collection with mapping methods between ViewModel and Model.

protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
           base.OnCollectionChanged(e);

  if (SyncIsDisabled)
                return;

            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
  foreach (var item in e.NewItems)
  AddToModel((TViewModel)item);
                    break;

                case NotifyCollectionChangedAction.Remove:
  foreach (var item in e.OldItems)
  RemoveFromModel((TViewModel)item);
                    break;

                case NotifyCollectionChangedAction.Reset:
                    underlyer.Clear();
                    break;

            }
        }

So when decomposing screens or models into ViewModels; or when you encounter an issue with a design, double-check everything is a ViewModel.

Tagged , , , ,

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 😉

Tagged , , , , , ,

Visual State Change In a Command

Using the Present VisualStateManager and the ViewRegistry we can now use a Present.Commands  decorator  to change the visual state of a ViewModel after succesful execution of the decorated command.

 The decorator has a number of overloads, the ViewModel to change state of can be passed in or returned by the do action; an action can be executed after the state transition as well.

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

The view has to then register itself with the registry and define a VisualState using the constant passed into the fluent method.

Tagged , , , , ,