Simplifying (View Model-) Data Binding Using Expression-Trees

Want to get rid of messy “PropertyChanged”-subscriptions and too many OnPropertyChanged(“…”) to manage value relations? Then DataBinder is what you’re looking for!
Read the rest of this entry »

Advertisements

MVVM Part 4: Commanding

Note: This posting is part of a series. See MVVM-Library for other parts and download.

Commanding is a very important topic in MVVM applications as it represents – together with Data Binding – the only mode of interaction between ViewModel and View.

Predefined Commands

In WPF there are three predefined commands:

Class Diagram: Predefined Commands in WPF

However, there is one problem: While ICommand encapsulates a “real” command that knows what to do itself, RoutedCommand and RoutedUICommand are dependant on the logical tree. Routing through the element tree, they look for a command binding which then invokes a method containing the actual implementation / logic.

So they are used totally different. Routed(UI)Commands are normally supplied as static fields or properties. ApplicationCommands is one example: The command declared there come with no logic; the addressee has to provide it.

Josh Smith’s Solution

Almost one year ago, Josh Smith published the article Using RoutedCommands with a ViewModel in WPF on Code Project (I recommend you reading through it).

In short: He introduced an easy way how to use RoutedCommands from within the ViewModel without connecting it to strong to the UI. He was able to do so by writing his own CommandBinding class. Unlike than many other people he did not write classes implementing ICommand and made them available in the ViewModel.

At this point: Many thanks to him for this really great article!!!

Why do I mention him and his article here? Well, my commanding solution is based on some of his ideas. Although I rewrote lots of his code you’ll still find some of the original code in my project.

My solution

The main players are the same – the members changed a bit:

Class diagram: My Solution

Note: VS seems to have problems with displaying delegates in class diagrams. The correct signature for CommandSink.RegisterCommand is “CommandSink.RegisterCommand(RoutedCommand command, Func<object, CommandState> getCommandStateCallback, Action<object> executeCallback)”.

CommandState

There was one main thing, I changed: Instead of providing a method CanExecute, I introduced GetCommandState which returns a new object, a CommandState.

What is a CommandState?

A command state gives information about the state a ViewModel has affecting the way of executing a command.

That may include:

  • If the command can be executed
  • Why a command can not be executed
  • What the execution of the command will change
  • Any warnings a user should notice before doing something

As the first point is essential, CommandState includes CanExecute which indicates exactly this. There are also two (non-abstract) subclasses ExecutableCommandState and NotExecutableCommandState which allow you using CommandStates without writing subclasses.

However, the other points can only be covered with custom inheritors of CommandState.

Why using CommandStates?

CommandStates help you implementing a very important factor for usability: dynamic feedback.

The UI informs the user, what will happen if he clicks on button a. In opposite to static tooltips which have to handle multiple cases, you build your tooltips dynamically and integrate the status information you get from a CommandState. You even can show why an action can not be done.

How should a CommandState look like?

In order to allow different UIs for your ViewModel classes, you should use almost no formatted data. That means: Work with enumerations, bools, … and collections of them.

As CommandState is derived from ViewModelBase, there are nearly unlimited possibilities to present the data to the user. (Note: A later posting will introduce some kind of factory for views that makes this process much easier again).

The sample project does it wrong: It uses one CommandState for everything that is only different in its message. Why am I not using multiple CommandStates then? Well, it’s not only the “ViewFactory” I did not introduce yet. I had to decide: Introduce them all in this article or writing that workaround. I chose the second. You’ll see later, why you should use them in this case 🙂

CommandSinkCommand

I already mentioned that my solution relies on “implementation-less” RoutedCommands.

In some cases, however, it isn’t possible to use them (especially when the command would never reach its target).

In order to be prepared to situations like these, CommandSinkCommand represents a routing-independent ICommand – you don’t have to write your code twice.

CommandingViewModel

CommandingViewModel implements ICommandSink (and of course ViewModelBase). Because of that it is able to be the target of routed commands.

How to declare and register your own commands?

I have written two snippets for that (“command” and “regCommand”). The sample project shows how commands are correctly declared and registered.

CommandStateExtension

CommandStateExtension simplifies evaluating the state of a command connected to a specific control. As the sample project contains an example for that, too, I won’t explain its usage further.

Sample Project

Screenshot of teh sample application Take a look at the screenshot on the left:

My sample project today is a simple counter where the buttons communicate with the ViewModel using RoutedCommands.

In additions there are labels indicating the “status” of each command.

Download it from MVVM-Library.

Posted in My interpretation of MVVM, WPF. Tags: , , , , , , . Comments Off on MVVM Part 4: Commanding

MVVM Part 3: ViewModelBase

Note: This posting is part of a series. See MVVM-Library for other parts and download.

Class Diagram of ViewModelBase It’s time for our first real “ViewModel” class: ViewModelBase.

As a ViewModel is – I already said before – databound to the UI it inherits NotifyKnownPropertyChanged to provide base support for Data Binding.

Data Binding to a WPF UI brings up another problem: The PropertyChanged event may only be raised in the UI thread.

In order to handle forbidden accesses from other threads and to make “Invoke”-scenarios possible, ViewModelBase remembers the dispatcher of the thread which created it. The methods for this purpose should be self-explanatory.

Note: ViewModel hides NotifyKnownPropertyChanged.OnPropertyChanged in order to perform a (debug-only) check ensuring it was called from the right thread. I thought a while if it would be better to make NotifyKnownPropertyChanged.OnPropertyChanged virtual and implement an auto-invoke solution.  As ViewModel classes are not thread safe (in general), however, but may be able to deal with callbacks (etc.) executing in other threads, this approach is ok in my opinion. Derived classes must not call OnPropertyChanged from another thread – if they do though there will only be an error when using the debug build.

Today, I won’t post an sample project because ViewModelBase makes only sense if it is inherited. You can download the updated ViewModel project (without the sample for the last part) here: MVVM-Library.

Posted in My interpretation of MVVM, WPF. Tags: , , , , , . Comments Off on MVVM Part 3: ViewModelBase

Change a Dependency Property in the setter of a bound property

ItemSelectionQuite a confusing title, but here is an example where this can be interesting (Note: I’m mot using my ViewModel library to keep this simpler).

Let’s say we have a list of values and the user can select one of them. Under special conditions (here in case that a checkbox is checked) we don’t want the user to change the selected item. It could look like in the screenshot on the right.

The following code would be logical to reach a behavior like that:

Foo.cs:

public sealed class Foo : INotifyPropertyChanged
{
    private string selectedItem;
    private bool denySelectionChange;

    public string SelectedItem
    {
        get
        {
            return this.selectedItem;
        }
        set
        {
            if (!String.Equals(this.selectedItem, value))
            {
                if (!this.DenySelectionChange)
                    this.selectedItem = value;

                this.OnPropertyChanged("SelectedItem");
            }
        }
    }
    public bool DenySelectionChange
    {
        get
        {
            return this.denySelectionChange;
        }
        set
        {
            if (this.denySelectionChange != value)
            {
                this.denySelectionChange = value;
                this.OnPropertyChanged("DenySelectionChange");
            }
        }
    }
    public ReadOnlyObservableCollection<string> Items
    {
        get;
        private set;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public Foo(ObservableCollection<string> items)
    {
        this.Items = new ReadOnlyObservableCollection<string>(items);
    }

    private void OnPropertyChanged(string p)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(p));
    }
}

Window1.xaml:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DockPanel>
        <CheckBox Content="Deny Selection change"
                  IsChecked="{Binding Path=DenySelectionChange}"
                  DockPanel.Dock="Bottom" />

        <ListBox ItemsSource="{Binding Path=Items}"
                 SelectedItem="{Binding Path=SelectedItem}" />
    </DockPanel>
</Window>

Window1.xaml.cs (only in order to fill the listbox):

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        Foo foo = new Foo(new ObservableCollection<string> { "Item 1", "Item 2", "Item 3", "Item 4" });
        this.DataContext = foo;
    }
}

However, you will still be able to change the selected item when the checkbox is checked.

I didn’t find a reason for that. It seems the data binding engine of the WPF doesn’t like it when you change a property while its informing the bound properties about a previous change.

But I have a solution 😉

It’s quite easy: Just change the property back (= raise PropertyChanged) after we have left the Setter.

How to achieve that?

That’s also quite easy: Use Dispatcher.BeginInvoke:

public string SelectedItem
{
    get //...
    set
    {
        if (!String.Equals(this.selectedItem, value))
        {
            if (!this.DenySelectionChange)
                this.selectedItem = value;

            Action action = () => this.OnPropertyChanged("SelectedItem");
            Dispatcher.CurrentDispatcher.BeginInvoke(action);
        }
    }
}

It should work now.

DotNetKicks Image
Posted in WPF. Tags: , , , . Comments Off on Change a Dependency Property in the setter of a bound property

MVVM Part 2: Property Changing

Note: This posting is part of a series. See MVVM-Library for other parts and download.

Remember that ViewModels are databound to the View?

How are they bound?

You might know that the binding engine in WPF relies on INotifyPropertyChanged for that:

The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.

For example, consider a Person object with a property called FirstName. To provide generic property-change notification, the Person type implements the INotifyPropertyChanged interface and raises a PropertyChanged event when FirstName is changed.

Property Names as strings…

PropertyChanged expects an instance of PropertyChangedEventArgs which provides a property PropertyName containing the name of the property that has changed as a string.

Thinking about my recently published posting Ban string literals from your code! you might be able to comprehend why I not really like that way: You can easily misspell the property name.

My solution

Class Diagram

Class Diagram

The classes

Property

The class Property represents a property (quite logical, isn’t it ;-)) with all its properties: The type that declares it, its name, its returning type and a callback that returns it value for an passed object.

It is the core of this project part.

Properties are immutable objects that are created via the static Factory-Method Create. You can either pass a PropertyInfo object or a Func<T, object> (speaking strictly a Expression<Func<T, object>>) which returns the value of the property. (Example later in this posting).

KnownPropertyChangedEventArgs

KnownPropertyChangedEventArgs is an EventArgs class that inherits PropertyChangedEventArgs and adds the property Property returning a Property 🙂 object.

INotifyKnowPropertyChanged

INotifyKnowPropertyChanged implements INotifyPropertyChanged and hides its PropertyChanged event. Instead it declares an event with the same name but of type EventHandler<KnownPropertyChangedEventArgs>.

So INotifyKnowPropertyChanged also informs about property changes. However, it identifies the changed property not via a simple string but with an object of the described Property class.

NotifyKnownPropertyChanged

NotifyKnownPropertyChanged provides a default implementation of the INotifyKnowPropertyChanged interface.

It maximizes comfort by providing two different methods:

  • OnPropertyChanged: Derived classes will call this method in order to notify about property changes.
  • NotifyPropertyChanged: This method will be called whenever a property changes (respectively when OnPropertyChanged is called). You can override it in order to be notified about property changes.

Sample project

The sample project today is quite small: It’s a simple console application to show how to use those classes. You can find it at MVVM-Library.

Code Snippet

I created a small snippet that helps declaring properties using this way of property change-tracking.

Your opinion

What do you think?

Any bugs / issues / suggestions?

Looking forward to your comments!

Posted in My interpretation of MVVM, WPF. Tags: , , , , , , . Comments Off on MVVM Part 2: Property Changing