JavaFX Properties: easily react to any property change

My experimentation with JavaFX led me to an interesting observation about the property system. There didn’t seem to be an easy way of registering a listener for any property change on a Java bean without registering handlers for each of the properties individually. Sometimes it is useful just to know that a property, any property, has changed and react to it.

I had a look through the JavaBeans specification to see if there was anything that already existed and realised I could use the existing PropertyChangeSupport class to propagate the JavaFX property changes to PropertyChangeEvents.

The basic requirements were:

  • I required a simple way to hook into the JavaFX property change system.
  • I needed to provide a way of letting observers register a PropertyChangeListener that would be notified when any property has changed.

The BoundPropertySupport class

I decided to follow in the footsteps of the authors of the PropertyChangeSupport class and wrap this up into a simple class that can be used by my JavaFX beans (rather than forcing them to inherit from a custom base bean class).

The source code looks like this:

public class BoundPropertySupport {
    private final PropertyChangeSupport changeHandler;
    private final Map<ObservableValue, String> propertyNameMap;
    private final ChangeListener changeListener;

    public BoundPropertySupport(Object bean) {
        this.changeHandler = new PropertyChangeSupport(bean);
        this.propertyNameMap = new HashMap();
        this.changeListener = new ChangeListener() {
            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                String propertyName = BoundPropertySupport.this.propertyNameMap.get(observable);
                BoundPropertySupport.this.changeHandler.firePropertyChange(propertyName, oldValue, newValue); 
            }
        };
    }

    public void raisePropertyChangeEventFor(Property property) {
        if (!this.propertyNameMap.containsKey(property)) {
            this.propertyNameMap.put(property, property.getName());
            property.addListener(this.changeListener);
        }
    }

    public void addChangeListener(PropertyChangeListener listener) {
        this.changeHandler.addPropertyChangeListener(listener);
    }

    public void removeChangeListener(PropertyChangeListener listener) {
        this.changeHandler.removePropertyChangeListener(listener)
    }
}

The class is very simple. It just wraps the provided PropertyChangeSupport class and provides a couple of methods which provide the features listed above. Notice that a single generic change listener is shared between all instances of registered properties as it doesn’t have to do anything specific to a certain JavaFX property implementation. Registration is provided via a simple method which allows for existing properties to be registered like this:

bps.raisePropertyChangeEventFor(getFooProperty())

Observers that are interested in the event can simply register like this:

aBean.addPropertyChangeListener(anExistingListenerReference);

Using it in a bean class

So lets see what this looks like when used in a bean class that also has some JavaFX properties:

public class Contact {
    private final BoundPropertySupport bps = new BoundPropertySupport(this);
    private final StringProperty firstName = new SimpleStringProperty(this, "firstName", "");
    private final StringProperty lastName = new SimpleStringProperty(this, "lastName", "");
    private final IntegerProperty age = new SimpleIntegerProperty(this, "age", 0);

    public Contact(String first, String last, int age) {
        this.firstNameProperty().set(first);
        this.lastNameProperty().set(last);
        this.ageProperty().set(age);

        this.bps.raisePropertyChangeEventFor(this.firstName);
        this.bps.raisePropertyChangeEventFor(this.lastName);
        this.bps.raisePropertyChangeEventFor(this.age);
    }

    public final StringProperty firstNameProperty() {
        return this.firstName;
    }

    public final StringProperty lastNameProperty() {
        return this.lastName;
    }

    public final IntegerProperty ageProperty() {
        return this.age;
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        this.bps.addChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        this.bps.removeChangeListener(listener);
    }
}

As you can see the BoundPropertySupport class is very simple to use and doesn’t add too much noise to the JavaFX bean. The observant amongst you might have noticed that I still have to register the change handler with each property but the code has been reduced to a minimum and is hidden away in the bean class; the observer simply registers a single property change handler and gets notified when any property changes.

Putting it together

The final code snippet shows a small program that consumes the Contact bean and is notified when any property on the bean class changes.

public static void main(String[] args) {

    // Create a Contact with some default values.
    Contact contact = new Contact("Ben", "Gale", 29);

    // Listen for any property change.
    contact.addPropertyChangeListener(new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            String formatString = "Property: %s, Old value: %s, new value: %s";
            System.out.println(String.format(formatString,
                                         evt.getPropertyName(),
                                         evt.getOldValue(),
                                         evt.getNewValue()));
        }
    });

    contact.firstNameProperty().set("John");
    contact.lastNameProperty().set("Smith");
    contact.ageProperty().set(30);

    contact.firstNameProperty().set("Fred");
    contact.lastNameProperty().set("Jones");
    contact.ageProperty().set(45);

    // These wont cause property change events to
    // occur because the values are the same...
    contact.firstNameProperty().set("Fred");
    contact.lastNameProperty().set("Jones");
    contact.ageProperty().set(45);
}

Conclusion

This post has provided a proof-of-concept for a small utility class that provides the ability to add listeners to a JavaFX bean that are interested in knowing when a property of the bean has changed without having to hook into the individual property changed events. The original need for this arose when I was looking into providing a validation hook for integrating beans validation into a JavaFX application but I would be interested to know if anyone else has any other uses for this.

The source code for the project can be located on my GitHub page.

Creating a simple JavaFX MVP example

I’ve been working on a small MVP framework for my JavaFX application and thought I would share the code I have so far.

I won’t be providing an overview of the pattern as there is plenty of existing literature on the subject already. If you are unfamiliar with the MVP pattern and it’s variants I suggest reading the following articles to get started:

A lot of the implementations can be open to interpretation. My intention is to provide something that honours the spirit of the pattern(s) whilst allowing me to make best use of the JavaFX features. Of course, if anyone feels my implementation is incorrect I welcome any constructive criticism.

The diagram below shows a simple overview of the way the example works.

MVP Diagram

JavaFX MVP overview

Summary:

  • The implementation is a variant of the Supervising Controller MVP pattern (the view can update itself using the model rather than having the presenter update the view as in the passive view variant).
  • The majority of the user interface is defined in FXML using Scene Builder.
  • The FXML files associated ‘controller’ class is basically a ‘code-behind’ for the view. It provides the logic that cannot be defined in FXML.
  • Each view references a presenter. The view references a concrete presenter (i.e. it is not exposed via an interface).
  • Each presenter holds a reference to the view which is exposed via an interface. This allows the presenter to be tested without having to fire up the UI.
  • The view can access the model via the presenter but does not hold a reference to it.
  • Both the view and presenter observe the model for updates.

The AbstractView class:

The generic AbstractView class provides a base class for all other views to derive from. The AbstractView is responsible for loading the associated FXML file and providing any logic that cannot be defined in FXML. I posted an example of creating a reusable JavaFX control which provides this exact functionality so I will use this as a base class for the AbstractView class.

The AbstractView depends upon a concrete presenter implementation. This is enforced by having a constructor that takes a presenter as a parameter. The view can then call methods on the presenter to communicate with it.

The AbstractView should implement an interface and pass itself to the presenter. This allows the presenter to communicate with the view and for the presenter to be tested without having to actually create the user interface.

The code for the AbstractView looks like this:

public abstract class AbstractView<P extends AbstractPresenter>
    extends UserControl {

    private final P presenter;

    public AbstractView(P presenter) {
        this.presenter = presenter;
        this.initialisePresenter();
    }

    private void initialisePresenter() {
        if (this.presenter == null){
            throw new IllegalStateException();
        }

        this.presenter.setView(this);
    }

    protected P getPresenter() {
        return this.presenter;
    }
}

The AbstractPresenter class:

The AbstractPresenter is the base class for all presenters which are responsible for acting upon the view and the model. The presenter will hold a direct reference to the model which it can observe and update. The presenter will act upon the view via an interface.

The AbstractPresenter provides methods for getting and setting both the model and view that the presenter acts upon. The getView() and setModel() methods are protected as they should not be accessible outside of the presenter.

Derived presenters should provide methods which can be called by the view in response to user input.

The AbstractPresenter class looks like this:

public abstract class AbstractPresenter<V, M> 
    implements Presenter<V, M> {

    private M Model;
    private V view;
    
    protected final V getView() {
        return this.view;
    }

    public final void setView(V view) {
        if (view == null) {
            throw new NullPointerException("view cannot be null.");
        }

        if (this.view != null) {
            throw new IllegalStateException("View has already been set.");
        }

        this.view = view;
    }

    @Override
    public final M getModel() {
        return this.model;
    }

    protected final void setModel(M model) {
        if (model == null) {
            throw new NullPointerException("model cannot be null.");
        }        
        this.modelProperty.set(model);
    }
}

The Model:

I have put no constraints on the object that is used as the model as you may not have control over the object that is used (it might be from an existing library, for example) although for best results I would recommend using an object that can be observed for property changes so that the view and presenter can be notified automatically when the model has changed.

Putting it all together:

For each view in your application you will need the following:

  • A model object.
  • A view interface.
  • A view class that derives from the AbstractView class and implements the view interface.
  • A presenter class that derives from the AbstractPresenter class and accepts a view and model of the appropriate types.
  • If your model is observable you will need to establish bindings between your user interface controls and the model.

You can then do something like this to create your views:

public class ViewFactory {
    
    public Node getFooView() {
        FooModel model = new FooModel();
        FooPresenter presenter = new FooPresenter(model);
        FooView view = new FooView(presenter);

        return view;
    }
}

Conclusion:

As you can see it is actually very easy to set up the bare bones of an application that uses the MVP pattern. Obviously this is very simple and misses a lot of essential functionality such as model validation and presenter-to-presenter communication but I have a few ideas for these features which may end up being posted about in the future.

Creating a reusable JavaFX custom control.

I’ve recently been experimenting with JavaFX 2 for an application I have been developing. On numerous occasions I have needed to create my own custom control that has it’s view defined in FXML and it’s logic defined in a custom class that derives from one of the Node classes (typically Parent). The official documentation provides a pretty good introduction to solving the problem but didn’t provide a solution that was nearly as robust as I liked.

The two main problems I have with this method are:

  1. Every custom control needs to duplicate the FXMLLoader logic which is usually exactly the same apart from the name of the FXML file.
  2. Most examples show the custom control deriving from one of the layout panes (such  as VBox). The fact that your root control lays the child controls out in a certain way is an implementation detail and the layout API should not be directly exposed from your control. It also makes the control brittle; if you want to change the way your controls are laid out you have to change both the FXML and the custom control class.

I (naively) tried to solve the second problem by deriving my custom control class from Region but this caused more problems than it solved. I used the fx:root construct in my FXML to point to my custom control but this did not work; every time I tried to open the FXML file in Scene Builder I was greeted with an error message that I was unable to resolve.

After some experimentation, I discovered that I could simply alter the fx:root construct to point to the Region class but this now means I am unable to add any controls in the FXML file as the Region class does not have a public getChildren() method. Making this method public in my derived class meant I was exposing the internal implementation of my control which I did not like.

Enter the custom Control

I decided to have a go at writing a custom control that would attempt to solve the above problems. Here are the main goals of the control:

  • Encapsulate the FXMLLoader logic.
  • Use a convention over configuration approach to loading the FXML file.
  • Hide the internal implementation details of the control (derived classes are responsible for providing a control specific API).
  • Ensure the loaded object graph is correctly resized to fit the bounds of the custom control.

The custom control will rather unimaginatively be called UserControl.

The implementation

The basic definition of the custom control class looks like this:

public abstract class UserControl extends Region {

    private final String resourcePath = "%s.fxml";

    public UserControl() {
        this.loadFXML();
    }

    private void loadFXML() {
        FXMLLoader loader = new FXMLLoader();

        loader.setController(this);
        loader.setLocation(this.getViewURL());

        try {
            Node root = (Node) loader.load();
            this.getChildren().add(root);
        }
        catch (IOException ex) {
            Logger.getLogger(UserControl.class.getName()).log(Level.SEVERE, null, ex);
        }    
    }

    private String getViewPath() {
        return String.format(resourcePath, this.getClass().getSimpleName());
    }

    private URL getViewURL() {
        return this.getClass().getResource(this.getViewPath());
    }
}

What this does is encapsulate the FXMLLoader so that derived controls do not have to concern themselves with loading the FXML file. There are a couple of helper methods which tell the FXMLLoader where to look for the FXML file.

The convention I have used is as follows:

  • The control expects the FXML file to have the same name as the control; a ShippingControl class would have an FXML file called ShippingControl.fxml.
  • The FXML file must be located in the same package as the control.

The loadFXML method then inserts the loaded object hierarchy into the custom controls child collection. This means that the FXML file can be changed without impacting the UserControl class. The internal representation of the control is also not exposed to the public.

Handling layout correctly

This code above covers 3 of the 4 goals of the custom control. All that is left is to ensure that the object hierarchy that is loaded is correctly resized to fit the bounds of the UserControl.

First of all you will need to override the layoutChildren method like this:

@Override
protected void layoutChildren() {
    for (Node node : getChildren()) {
        layoutInArea(node, 0, 0, getWidth(), getHeight(), 0, HPos.LEFT, VPos.TOP);
    }
}

This basically enumerates the UserControls child collection (which will always only contain a single child, the root of the FXML file) and resizes it to fit the UserControls bounds.

Note: a micro optimisation could be made by keeping a reference to the root node and passing it directly to the layoutChildren method negating the need to enumerate the child collection but I have decided against this to keep the sample as simple as possible.

This actually caters for the layout in most cases but will fail if the maxWidth and maxHeight properties of the root control are explicitly set to values smaller than the UserControls bounds in the FXML file. To overcome this I introduced another helper method that overrides these settings to ensure the control always sizes correctly. The method looks like this:

private void setMaxSize(Node node) {
    if (node != null && node instanceof Region) {
        Region region = (Region) node;
        region.setMaxWidth(Double.MAX_VALUE);
        region.setMaxHeight(Double.MAX_VALUE);
    }
}

This method is called directly after the FXML structure is loaded in the loadFXML method. All it does is check to see if the control is resizable, and if so, sets the maximum width and height values to Double.MAX_VALUE which tells JavaFX that the control can be sized as big as possible which ensures any resizeable controls fit the bounds of the UserControl.

Using the custom control

All that is required to use the UserControl class is to derive a new control from it and provide an FXML file. To demonstrate this I will show a simple custom control called FullNameControl. The control will have two TextField controls for entering a persons first and last name. the control will also include a Label that is automatically updated to show the persons full name. The UI will be defined in FXML and the logic will be defined in the custom control class.

The FXML will not be shown here (it is included in the source code download) but the visual output looks like this:

FXML output

The full source code of the FullNameControl class looks like this:

public class FullNameControl extends UserControl {

    @FXML
    private TextField firstName;
    @FXML
    private TextField lastName;
    @FXML
    private Label fullName;
    
    public FullNameControl() {
        this.fullName.textProperty().bind(
                Bindings.when(Bindings.equal(firstName.textProperty(), "")
                .and(Bindings.equal(lastName.textProperty(), "")))
                .then("[enter first and last names]")
                .otherwise(Bindings.format(
                    "Your full name is: %s %s", 
                     firstName.textProperty(), 
                     lastName.textProperty())));
    }
}

When the application is run the window displays the control (which resizes correctly) and allows the user to input their first and last names. The label is updated to reflect the user input.

Note that the code in the UserControl base class takes care of binding the controls in the FXML file to the private fields in the class.

Before any names are added:

UI before input

After the user has entered their first and last names:

UI after input

The full source code for the control and the sample is available on my GitHub page.

MVVM compliant child window in Silverlight

For anyone who has used the Silverlight ChildWindow, you will be aware that it doesn’t play with the MVVM pattern very well out of the box. I found a couple of solutions on-line via the magic of Google but they were either over-complicated or not MVVM compliant (one of the solutions instantiated the ChildWindow directly within the viewModel!).

The basic idea

After a bit of thought I realised that the answer was actually fairly straightforward; abstract the code that instantiates the ChildWindow into a separate class and allow this to be controlled using properties bound to a viewModel.

Silverlight (and WPF) allows you to create properties that can be attached to any other element that is derived from DependencyObject so the idea is to create a class called DialogService that exposes a set of properties which initialise and control the display of the ChildWindow.

The properties

I wanted the class to be fairly simple with the minimal amount of properties. Basically the class should only be responsible for opening and closing the ChildWindow and setting a few other basic properties; everything else should be controlled via the viewModel.

Here is the list of properties I decided to implement:

  • IsShowing: This determines if the dialog is currently being displayed or not.The default value is false.
  • HasCloseButton: This is used to set the same property on the ChildWindow when it is being displayed. The default value is true;
  • Title: This sets the title of the ChildWindow. The default is string.Empty.
  • Content: This is used to set the actual content to be displayed in the window. The default value is null.
  • Resources: This will allow you to pass resources to the window. The default value is an empty resource dictionary.

The Dependency property definitions are all fairly standard as can be seen below:

public static readonly DependencyProperty IsShowingProperty =
    DependencyProperty.RegisterAttached(
    "IsShowing",
    typeof(bool),
    typeof(DialogService),
    new PropertyMetadata(false, IsShowingChanged));

public static readonly DependencyProperty TitleProperty =
    DependencyProperty.RegisterAttached(
    "Title",
    typeof(string),
    typeof(DialogService),
    new PropertyMetadata(string.Empty, TitleChanged));

public static readonly DependencyProperty HasCloseButtonProperty =
    DependencyProperty.RegisterAttached(
    "HasCloseButton",
    typeof(bool),
    typeof(DialogService),
    new PropertyMetadata(true));

public static readonly DependencyProperty ContentProperty =
    DependencyProperty.RegisterAttached(
    "Content",
    typeof(object),
    typeof(DialogService),
    new PropertyMetadata("Content", ContentChanged));

internal static readonly DependencyProperty ResourcesProperty =
    DependencyProperty.RegisterAttached(
    "ResourcesInternal",
    typeof(ResourceDictionary),
    typeof(DialogService),
    null);

Of particular interest is the resources property.The reason I included this property was that I wanted to be able to tell the ChildWindow to render it’s content using DataTemplates which would allow the actual view to be defined in a UserControl and switched dynamically when the content changes. Originally I had intended to just add the DataTemplates to the resources dictionary of the element that is consuming the attached properties but this would not work as the ChildWindow does not have a parent and so the resources are not inherited by the ChildWindow. You may have also noticed that the dependency property is marked as internal. This is because I want the xaml parser to call my static GetValue() method instead of the dependency property as it has some extra code that creates a resource dictionary if it is set in xaml. See the source code sample for further details.

I have also provided the standard get and set value methods required by attached properties. Again, these are all pretty standard and simply delegate to the GetValue() and SetValue() methods on DependencyObject.

How it works

There are a couple of things to consider in the implementation of the DialogService class.

  • The showing and hiding of the ChildWindow.
  • Setting basic properties on the ChildWindow based on the properties in the DialogService class.
  • Updating properties in the ChildWindow when they change in the DialogService class.

The first two items are handled in the property changed handler for the IsShowing property. Basically if the value is set to true, set the properties and show the ChildWindow, otherwise hide it.

Here is the full implementation of the IsShowing property changed handler:

private static void IsShowingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
    var element = sender as FrameworkElement;

    if ((bool)args.NewValue)
    {
        if (dialog == null)
        {
            dialog = new ChildWindow();
            dialog.Title = GetTitle(element);
            dialog.HasCloseButton = GetHasCloseButton(element);
            dialog.Content = GetContent(element);

            dialog.Resources.MergedDictionaries.Add(GetResources(element));

            dialog.Closed += dialogClosed;
            cachedElement = element;

            dialog.Show();
        }
    }
    else
    {
        if (dialog != null)
        {
            dialog.Close();
        }
    }
}

The third item is handled by simply using property changed handlers to propogate the values to the  ChildWindow. The key thing to remember here is that the handlers should check if the window is actually being displayed, otherwise there is no need to do any work in the property changed handlers (as the values will be set the next time IsShowing is set to true).

To get this working I have a DialogViewModel which basically exposes the properties required for binding to the DialogService. The reason for this is that you can enhance existing viewModels by using composition rather than having to specify the same properties over and over again. In effect the DialogViewModel is acting as a sort of controller for opening and closing the ChildWindow. I use a Messenger class to send a message to the DialogViewModel which then uses the information passed to instantiate and show the ChildWindow.

Note: I have not shown the viewModel implementations as they are specific to my application and this control is designed to work in an MVVM compliant way so any viewModel can be bound providing it exposes relevant properties.

To following example shows how you would use the DialogService class in your xaml.

<UserControl x:Class="Application.MainPage"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                xmlns:dialog="clr-namespaceApplication.Controls"
                dialog:DialogService.IsShowing="{Binding DialogView.IsShowing, Mode=TwoWay}"
                dialog:DialogService.Title="{Binding DialogView.DisplayText}"
                dialog:DialogService.Content="{Binding DialogView.CurrentView}"
                dialog:DialogService.HasCloseButton="{Binding DialogView.CanUserClose}">

<dialog:DialogService.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Assets/DialogResources.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</dialog:DialogService.Resources>

Conclusion

The DialogService provides an MVVM compliant way of displaying ChildWindows in Silverlight. The source code can be downloaded from my GitHub page.

Rich property support in WPF viewModels (part 3)

It is important for a programmer to be critical of their own work. Sometimes you have invested a lot of time in a piece of code that for various reasons isn’t working or just doesn’t smell right and you have to be honest with yourself so that you don’t dig yourself deeper into the hole you have already created.

The code that was the subject of my last two posts, whilst working fine, posed a number of problems for me the main one being the additional complexity required in both programming the solution and using it.

I originally started developing this code to solve the problem of raising property changed events for properties that depend on other properties. The solution presented in my previous blog post required a number of interfaces and base class before I could even solve the problem and in hindsight this should have set off alarm bells immediately.

Back to the drawing board.

Lets recap the problem I was actually trying to solve. The common way of raising property changed events for dependent properties looks like this:

public int SomeProperty
{  
    get
    {
        someProperty = value;
        RaisePropertyChangedEvent("SomeProperty");
        RaisePropertyChangedEvent("FirstDependentProperty");
        RaisePropertyChangedEvent("SecondDependentProperty");
    }
}

This is brittle for the following reasons:

  • The property names are ‘stringly-typed’.
  • The property should not have to know which other properties depend on it’s value (the relationship should be defined the other way round).

When you take a step back the problem is actually fairly simple. If a property (property a) depends on the value of another (property b) then the property changed event needs to be raised for property a when the value of property b changes.

Josh Smith’s MVVM Foundation library provides a class called PropertyChangedObserver which provided 90% of the functionality I required. The only thing that was missing was the ability to map dependencies and the ability to re-raise the property changed event.

I decided to handle this by keeping the map of properties and their dependencies in my viewModel base class. I then subscribe to the property changed event and check for any dependencies and raise the property changed event for them as required.

The code for the ViewModel class is actually fairly simple so I will show it in it’s entirety.

public class ViewModel : INotifyPropertyChanged
{
    private const string error = 
        "'{0}' did not provide a property name. Please provide a lambda expression like 'p => p.PropertyName'";

    private IDictionary<string, IList<string>> dependenciesMap = new Dictionary<string, IList<string>>();

    public ViewModel()
    {
        this.PropertyChanged += ViewModel_PropertyChanged;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public void RegisterDependencies<T>(Expression<Func<T, object>> property, params Expression<Func<T, object>>[] dependencies)
    {
        string propertyName = GetPropertyName(property);
        if (string.IsNullOrEmpty(propertyName))
            throw new ArgumentException(string.Format(error, "property"));

        foreach (Expression<Func<T, object>> expr in dependencies)
        {
            IList<string> dependenciesList;
            string dependencyName = GetPropertyName(expr);
            if (string.IsNullOrEmpty(dependencyName))
                throw new ArgumentException(string.Format(error, "dependencies"));

            if (dependenciesMap.TryGetValue(dependencyName, out dependenciesList))
            {
                if (!dependenciesList.Contains(propertyName))
                {
                    dependenciesList.Add(propertyName);
                }
            }
            else
            {
                dependenciesList = new List<string>();
                dependenciesList.Add(propertyName);
                dependenciesMap[dependencyName] = dependenciesList;
            }
        }
    }

    void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        IList<string> dependencies;
        if (dependenciesMap.TryGetValue(e.PropertyName, out dependencies))
        {
            foreach (string item in dependencies)
            {
                RaisePropertyChangedEvent(item);
            }
        }
    }

    private static string GetPropertyName<T>(Expression<Func<T, object>> expression)
    {
        var lambda = expression as LambdaExpression;

        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = lambda.Body as UnaryExpression;
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = lambda.Body as MemberExpression;
        }

        if (memberExpression != null)
        {
            PropertyInfo info = memberExpression.Member as PropertyInfo;

            if (info != null)
            {
                return info.Name;
            }
            else
            {
                return null;
            }
        }
        else
        {
            return null;
        }
    }
}

Then in your viewModels you just need to call the following code:

RegisterDependencies<SalesOrder>(p => p.TotalSalesCommission, p => p.salesCommission, p => p.TotalPrice);

Conclusion

This offers an arguably simpler way of notifying dependent properties of changes compared to my last post. A code sample is available here. Take a look at the viewModel class definitions and see how much simpler they are in comparison to the previous example supplied with my last post.

Rich property support in WPF viewModels (Part 2)

In my last post I started some work on a basic implementation of JavaFX style properties for use in WPF view models.

During the past week I have been experimenting with a few ideas and have made some minor improvements to the code.

Getting started

First of all I have created some basic interfaces for the properties to implement. These are based loosely on those in the JavaFX API (only they are simpler and the interface hierarchy is not as deep).

public interface IObservableProperty<T> : INotifyPropertyChanged
{
    T Value { get; }
}

The first interface IObservableValue simply tells implementers that it should have a property of type T and that it raises a PropertyChanged event.

public interface IReadOnlyProperty<T> : IObservableProperty<T>
{
    object Context { get; }
    string Name { get; }
}

The second interface IReadOnlyProperty provides access to some contextual information about an IObservableValue. The idea is that this will be used by the property system to determine the name of the property and the containing object. This interface is not really put to use in these examples so don’t worry to much about it.

public interface IWritableProperty<T>
{
    T Value { set; }
}

The final interface IWritableProperty simply provides the ability to set the property value. The reason for separating the interfaces into read-only and write-only interfaces is that certain properties are not settable such as those that compute their values based on other properties.

Property implementations

The next step was to provide some concrete implementations of the above interfaces.

The first class Property is pretty much the same as that from my last post except it implements the interfaces mentioned above. The code is provided below but I won’t comment any further on it here as it is pretty self explanatory.

public class Property<T> : IReadOnlyProperty<T>, IWritableProperty<T>
{
    private string _name;
    private bool shouldRaiseNotifications = true;
    private T _value = default(T);
    private object _context;

    public event PropertyChangedEventHandler PropertyChanged;

    public Property(string propertyName) : this(propertyName, null) { }

    public Property(string propertyName, object context)
    {
        if (string.IsNullOrEmpty(propertyName))
            throw new ArgumentException("name");

        this._name = propertyName;
        this._context = context;
    }

    public object Context { get { return _context; } }

    public string Name { get { return _name; } }

    public T Value
    {
        get { return GetValue(); }
        set { SetValue(value); }
    }

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected virtual void SetValue(T value)
    {
        if (!EqualityComparer<T>.Default.Equals(_value, value))
        {
            _value = value;

            if (shouldRaiseNotifications)
            {
                shouldRaiseNotifications = false;
                RaisePropertyChangedEvent(_name);
            }
        }
    }

    protected virtual T GetValue()
    {
        shouldRaiseNotifications = true;
        return _value;
    }
}

The next class, BoundProperty is much more interesting. It basically maintains a list of other properties (it’s dependencies) and raises the PropertyChanged event when any of them change.

In my last post I created a calculated property called BoundStringProperty which provided a single Format method to return a formatted string. The formatted string value was re-evaluated whenever any of the dependencies changed.

This worked except that it could only do one thing (format a string). I wanted to create a a property that was bound to others but perform any calculation you wanted.

The JavaFX API has what is called the ‘low level’ binding API. Essentially it is an object that takes a list of dependencies and defines a ComputeValue method. Java’s anonymous classes make it very easy to create a new object and override the ComputeValue method. This can’t be done in C# and I didn’t want to have a different class for every type of calculation I wanted to perform. Luckily C# has delegates.

public class BoundProperty<T> : IObservableProperty<T>
{
    private Func<T> _expression;
    private IList<INotifyPropertyChanged> _dependencies = new List<INotifyPropertyChanged>();
    private string _name;

    public event PropertyChangedEventHandler PropertyChanged;

    public BoundProperty(string propertyName, Func<T> valueCalculation)
    {
        if (string.IsNullOrEmpty(propertyName))
            throw new ArgumentException("name");

        if (valueCalculation == null)
            throw new ArgumentNullException("valueCalculation");

        this._name = propertyName;
        this._expression = valueCalculation;
    }

    public void BindDependencies(params INotifyPropertyChanged[] dependencies)
    {
        foreach (INotifyPropertyChanged inpc in dependencies)
        {
            inpc.PropertyChanged += updateBinding;
            _dependencies.Add(inpc);
        }
    }

    void updateBinding(object sender, PropertyChangedEventArgs e)
    {
        RaisePropertyChangedEvent(_name);
    }

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public T Value
    {
        get { return _expression == null ? default(T) : _expression(); }
    }
}

The BoundProperty class is very straightforward. It takes a Func<T> via it’s constructor and a list of dependencies via it’s BindDependencies method. When any of the dependencies change the PropertyChanged event is raised and this notifies clients that the value can be re-calculated. The value is re-calculated when the property value is asked for via it’s getter.

An example application

In my last post I provided a link to this blog post which explained some of the shortcomings of using INotifyPropertyChanged with viewModels.

The sample application provided here is based on the code from that blog post to show that my property implementation overcomes some of these problems.

The XAML for the application’s main window looks like this:

<Window x:Class="PropertyDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:PropertyDemo"
        Title="Rich property demo"
        Height="350"
        Width="525">
    <Window.DataContext>
        <viewModel:SalesOrder />
    </Window.DataContext>

    <StackPanel HorizontalAlignment="Center"
                VerticalAlignment="Center">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <Label Content="Item price:"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Center" />
            <Label Content="Quantity"
                   Grid.Row="1"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Center" />
            <Label Content="Sales commision:"
                   Grid.Row="2"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Center" />
            <Label Content="Total price:"
                   Grid.Row="3"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Center" />
            <Label Content="Total commision:"
                   Grid.Row="4"
                   HorizontalAlignment="Right"
                   VerticalAlignment="Center" />
            <Label Content="{Binding TotalPrice}"
                   Grid.Column="1"
                   HorizontalAlignment="Left"
                   Grid.Row="3"
                   VerticalAlignment="Center"
                   ContentStringFormat="c" />
            <Label Content="{Binding TotalSalesCommision}"
                   Grid.Column="1"
                   HorizontalAlignment="Left"
                   Grid.Row="4"
                   VerticalAlignment="Center"
                   ContentStringFormat="c" />
            <TextBox Grid.Column="1"
                     HorizontalAlignment="Left"
                     Text="{Binding ItemPrice}"
                     VerticalAlignment="Center"
                     Width="200" />
            <TextBox Grid.Column="1"
                     HorizontalAlignment="Left"
                     Grid.Row="1"
                     Text="{Binding Quantity, UpdateSourceTrigger=PropertyChanged}"
                     VerticalAlignment="Center"
                     Width="200" />
            <TextBox Grid.Column="1"
                     HorizontalAlignment="Left"
                     Grid.Row="2"
                     Text="{Binding SalesCommision}"
                     VerticalAlignment="Center"
                     Width="200" />
        </Grid>
    </StackPanel>
</Window>

The application provides a user interface to enter a sales price for a product, the quantity on order and the amount of commission per part and calculates the total order amount as well as the total amount of commission. A screenshot is shown below:

Rich property demo 2

The two viewModel classes look like this:

public class Order : ObservableObject
{
    public readonly Property<decimal> itemPriceProperty = new Property<decimal>("ItemPrice");
    public readonly Property<int> quantityProperty = new Property<int>("Quantity");
    public readonly BoundProperty<decimal> totalPriceProperty;

    public Order()
    {
        itemPriceProperty.PropertyChanged += Property_PropertyChanged;
        quantityProperty.PropertyChanged += Property_PropertyChanged;

        totalPriceProperty = new BoundProperty<decimal>("TotalPrice", 
            () => ItemPrice * Quantity);  

        totalPriceProperty.PropertyChanged += Property_PropertyChanged;
        totalPriceProperty.BindDependencies(itemPriceProperty, quantityProperty);
    }

    void Property_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        RaisePropertyChangedEvent(e.PropertyName);
    }

    public decimal ItemPrice
    {
        get { return itemPriceProperty.Value; }
        set { itemPriceProperty.Value = value; }
    }

    public int Quantity
    {
        get { return quantityProperty.Value; }
        set { quantityProperty.Value = value; }
    }

    public decimal TotalPrice
    {
        get { return totalPriceProperty.Value; }
    }
}
public class SalesOrder : Order
{
    public readonly Property<decimal> salesCommisionProperty = 
        new Property<decimal>("SalesCommision");
    
    public readonly BoundProperty<decimal> totalSalesCommisionProperty;

    public SalesOrder()
    {
        salesCommisionProperty.PropertyChanged += Property_PropertyChanged;

        totalSalesCommisionProperty = new BoundProperty<decimal>("TotalSalesCommision", 
            () => TotalPrice * SalesCommision);

        totalSalesCommisionProperty.BindDependencies(totalPriceProperty, salesCommisionProperty);
        totalSalesCommisionProperty.PropertyChanged += Property_PropertyChanged;
    }

    void Property_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        RaisePropertyChangedEvent(e.PropertyName);
    }

    public decimal SalesCommision
    {
        get { return salesCommisionProperty.Value; }
        set { salesCommisionProperty.Value = value; }
    }

    public decimal TotalSalesCommision
    {
        get { return totalSalesCommisionProperty.Value; }
    }
}

Basically, the viewModel provide a number of properties that can be accessed and updated. They both also provide a calculated property that is based on the value of other properties. Note the following:

  • Properties do not need to know which other properties depend on them (so the setters are kept simple)
  • The derived class calculates its value based on a property from it’s base class.

Conclusion

There is still a long way to go but this is definitely a step in the right direction. In order to improve this further I think the following changes will need to be made:

  • The BoundProperty should cache it’s value rather than recalculating it every time.
  • Dependencies should be held as weak references so that they can be automatically freed when no other objects reference them.
  • Improvements need to be made to bound properties so that complex expressions can be built up.
  • Property values should be validated.
  • The boilerplate code for hooking up events needs to be reduced.

The source code for this sample is available here.

Rich property support in WPF viewModels

I have recently been playing around with JavaFX and one of the things I love about it is the rich property support that is provided by the framework. For anyone unfamiliar with JavaFX, it has a property system that supports change notifications and complex binding. Each ‘property’ is represented by a class that implements a number of interfaces that support observability and binding. These properties are then exposed using the standard Java Beans pattern. (take a look at this article if you’re interested in getting a flavour of what’s possible without getting bogged down in the details).

Now if this sounds similar to a dependency property then you’d be correct. One thing that I like about the Java implementation, however, is that the properties are not tied to JavaFX I.E. any POJO class can use properties and this is something that I wish we could do with WPF properties (without having to derive a viewModel from DependencyObject).

While dependency properties can be used in your viewModels if you chose, there are a number of drawbacks to this approach which have been covered before.

This leaves us with viewModels that use standard CLR properties and provide change notification via the INotifyPropertyChanged interface. This is simple to set up and get started and the basic plumbing can be built into a base class but the solution isn’t without it’s problems (the most annoying of which is discussed here).

I decided to experiment with a rich property system for my WPF viewModels to try and overcome some of the problems inherent with the INotifyPropertyChanged method.

Warning

This example was thrown together in a couple of hours as a proof of concept and is in no way considered production ready. There is a lot of room for improvement. Use the code at your own risk.

The application

Before building the property system I needed an application to test it on. The application is a simple, single windowed application with two text boxes and a label. The user can enter their first and last names into the text boxes and the label will be updated to show the full name of the user. The XAML for this application looks like this:

<Window x:Class="PropertyDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <viewModel:ViewModel/>
    </Window.DataContext>
    <StackPanel>
        <TextBox Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBox Text="{Binding LastName, UpdateSourceTrigger=PropertyChanged}" />
        <Label Content="{Binding FullName}"/>
    </StackPanel>
</Window>

The property class

The next step is to create a class that represents a property. The basic idea here is the class will wrap a ‘value’ of some sort and provide notifications when the property value has changed. The code is pretty self explanatory so I won’t explain it much further here.

public class Property<T> : ObservableObject
{
    protected string propertyName;
    protected bool shouldRaiseNotifications = true;
    protected T propertyValue = default(T);

    public Property(string name)
    {
        if (string.IsNullOrEmpty(name))
            throw new ArgumentException("name");

        propertyName = name;
    }

    public virtual T GetValue()
    {
        shouldRaiseNotifications = true;
        return propertyValue;
    }

    public virtual void SetValue(T value)
    {
        if (!EqualityComparer<T>.Default.Equals(propertyValue, value))
        {
            propertyValue = value;

            if (shouldRaiseNotifications)
            {
                shouldRaiseNotifications = false;
                RaisePropertyChangedEvent(propertyName);
            }
        }
    }
}

One point of interest is the shouldRaiseNotifications variable which tells the property whether it should raise notifications when the value has changed which is a feature I have shamelessly borrowed from JavaFX properties. What this means is that unless the new property is accessed via the GetValue() method, further change notifications will not be raised which offers performance enhancements if a lot of properties are in use. Note that if bound to a WPF view the binding will be re-evaluated immediately which makes this feature redundant in this example, however my intention is for the property type to be used in other scenarios where this feature will be handy.

The bound property class

A bound property is very similar to a property except that it’s value is calculated based on that of other properties (dependencies). The bound property cannot have its value set directly. The code looks like this:

public abstract class BoundProperty<T> : Property<T>
{
    public BoundProperty(string name) : base(name) { }

    private IList<INotifyPropertyChanged> dependencies = new List<INotifyPropertyChanged>();

    protected IList<INotifyPropertyChanged> Dependencies
    {
        get { return dependencies; }
    }

    public override void SetValue(T value)
    {
        throw new Exception("Bound property values cannot be set");
    }
}

On its own the BoundProperty class doesn’t actually do anything; you need a concrete implementation that knows how to calculate a value from its dependencies.

For this example I have create a simple BoundStringProperty class that supports a Format() method. The Format method will behave like the string.Format() method. The BoundStringProperty object will become invalid if any of the values used in the format string become invalid signalling that the value needs to be recalculated. Note that the value isn’t actually recalculated until it is accessed via the GetValue() method.

The code for the BoundStringProperty class looks like this:

public class BoundStringProperty : BoundProperty<string>
{
    private string cachedFormatString;

    public BoundStringProperty(string name) : base(name) { } 

    public void Format(string formatString, params Property<string>[] properties)
    {
        foreach (INotifyPropertyChanged inpc in properties)
        {
            inpc.PropertyChanged += updateBinding;
            Dependencies.Add(inpc);
        }

        cachedFormatString = formatString;
    }

    void updateBinding(object sender, PropertyChangedEventArgs e)
    {
        RaisePropertyChangedEvent(propertyName);
    }

    public override string GetValue()
    {
        IList<string> values = new List<string>();

        foreach(Property<string> prop in Dependencies)
        {
            values.Add(prop.GetValue());
        }

        return string.Format(cachedFormatString, values.ToArray());
    }
}

The viewModel

The next step is to define a viewModel which utilises the property classes.

public class ViewModel : ObservableObject
{
    private Property<string> firstNameProperty = new Property<string>("FirstName");
    private Property<string> lastNameProperty = new Property<string>("LastName");

    private BoundStringProperty fullNameProperty = new BoundStringProperty("FullName");

    public ViewModel()
    {
        firstNameProperty.PropertyChanged += Property_PropertyChanged;
        lastNameProperty.PropertyChanged += Property_PropertyChanged;
        fullNameProperty.PropertyChanged += Property_PropertyChanged;

        fullNameProperty.Format("Your full name is {0} {1}.", 
            firstNameProperty, lastNameProperty);
    }

    void Property_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        RaisePropertyChangedEvent(e.PropertyName);
    }

    public string FirstName
    {
        get { return firstNameProperty.GetValue(); }
        set { firstNameProperty.SetValue(value); }
    }

    public string LastName
    {
        get { return lastNameProperty.GetValue(); }
        set { lastNameProperty.SetValue(value); }
    }

    public string FullName
    {
        get { return fullNameProperty.GetValue(); }
    }
}

Now when you run the application, you will see that this behaves as expected with the label being updated when the values in the text boxes change. Note that neither the FirstName or LastName properties need to know that the FullName property is dependent upon their values.

Conclusion

Obviously there is still a lot of work to be done before this becomes useful in a real world WPF application but I think this is something worth experimenting with a bit further.

As it stands, the following issues need resolving:

  • The ViewModel needs to hook up to the PropertyChanged event of all properties so that it can propagate the event to the view.
  • The bound property currently keeps strong references to all of its dependencies which could be a potential source of memory leaks.
  • Bound properties will only be useful with a lot of architecture so that complex binding expressions can be built up.

The source code is available here.