DeutschEnglish

Feb 24

A smart ICommand implementation #4

In the previous blog post, we discussed an approach that allows to specify an MVVM Command’s CanExecute condition as well as the properties this condition depends on in one line, without the need of adding information about participating commands to the properties’ setter methods.

This solution improves maintainability by positioning code snippets that syntactically belong together nearby each other, but it still contains redundant code parts that are defined more than once: All of the properties that are already referenced within the CanExecute condition need to be repeated in separate fields – this can definitely be shortened!

Automatic retrieval of dependent properties:

If we can automatically retrieve a property’s name (as string value) out of an expression that defines the property (as mentioned in the previous blog post and described in detail in Thomas Mutzl’s article A smart MVVM command), why shouldn’t we be able to retrieve all referenced properties’ names directly from the Command’s CanExecute condition? This is in fact possible – let’s take a look at how to implement such an optimization:

What have we done so far? The last version of the DelegateCommand constructor presented in the previous blog post has the following signature:

public DelegateCommand(Action<object> action, Func<object, bool> condition,
		INotifyPropertyChanged viewmodel, params Expression<Func<object>>[] dependsOnProperties)

Our aim is to get rid of the dependsOnProperties parameter, so let’s omit it. Instead, we pass the condition as lambda expression:

public DelegateCommand(Action<object> action, Expression<Func<object, bool>> condition,
		INotifyPropertyChanged viewmodel)

Apart from the missing list of dependent properties, this method can be called the same way as the previous one, since syntactically there is no difference between passing a Func and an Expression, except for one case: If you didn’t specify the condition inline (as lambda expression) but in a separate method, you’ll need to convert this method call to a lambda expression, for example:

public MyViewmodel()
{
	SearchCommand = new DelegateCommand(SearchMethod, () => IsSearchAllowed());
}

private bool IsSearchAllowed()
{
	// Evaluate condition
}

However, in real life most conditions won’t be too complex and will usually depend on only one or two properties, so it should be possible to define the condition’s body as lambda expression directly within the Command’s initialization – let’s focus on this case for the moment:

public MyViewmodel()
{
	SearchCommand = new DelegateCommand(SearchMethod,
			() => IsLoggedIn && !String.IsNullOrEmpty(Keywords));
}

Of course, also the constructor’s body needs to be adapted to reflect this changed signature. We need to

  1. convert the condition that has been passed as lambda expression back to a standard Func type to be able to store it in the private _canExecute field (which the Command’s CanExecute() method depends on), and
  2. fill the list of dependent properties which, in the old version, had been passed explicitly.

The first task is easily solved by compiling the lambda expression and storing it as the global _canExecute condition:

_canExecute = canExecute.Compile();

The second task is much more complex – after all, this is what we’ve been after since the beginning: Getting rid of an explicitly passed list of dependent properties and magically retrieving them from the condition’s body! Let’s extract that logic to a separate helper method ParseExpresionTree():

private void ParseExpresionTree(Expression inputExpression, List<string> properties)

The lambda expression that represents the Command’s condition is structured as tree: It contains several other expressions that are combined with each other through operations. There exist different types of expressions – the one we’re after is MemberExpression as this one represents a call to a member, e.g. to a property (after all, this is what we’re looking for: each call to a property must be found, as we need to register to all those properties’ PropertyChanged events!).

So, if we’re dealing with a MemberExpression, check if the member that shall be called is a property, and in that case retrieve its name and store it in the global list of dependent properties:

private void ParseExpresionTree(Expression inputExpression, List<string> properties)
{
	if (inputExpression is MemberExpression)
	{
		var e = inputExpression as MemberExpression;
		var member = e.Member;
		if (member is PropertyInfo)
		{
			PropertyInfo property = member as PropertyInfo;
			Type owner = property.DeclaringType;
			if (owner.GetTypeInfo().ImplementedInterfaces.Contains(typeof(INotifyPropertyChanged)))
			{
				string propertyName = property.Name;
				if (!properties.Contains(propertyName))
					properties.Add(propertyName);
			}
		}
	}
	else
	{
		// process all other types of expressions...
	}
}

The problem is: To find those MemberExpressions, we need to parse the whole tree, and this tree will contain various other expressions that all need to be processed in a different way. For example, if the tree contains a ConditionalExpression at some position (which is an expression that represents an if block), we need to divide this part of the tree into three sub-parts:

  • the expression that shall be tested,
  • the expression that shall be invoked if the test returns true, and
  • the expression that shall be invoked if the test returns false.

Each of these three sub-parts again is represented as expression of some type, and each of those three expressions needs to be processed separately to check if one of them contains a MemberExpression – we do this by calling the ParseExpresionTree() method recursively, passing each of the three sub-expressions:

private void ParseExpresionTree(Expression inputExpression, List<string> properties)
{
	if (inputExpression is MemberExpression)
	{
		// retrieve property name as shown above
	}
	else if (inputExpression is ConditionalExpression)
	{
		var e = inputExpression as ConditionalExpression;
		ParseExpresionTree(e.Test, properties);
		ParseExpresionTree(e.IfTrue, properties);
		ParseExpresionTree(e.IfFalse, properties);
	}
	else
	{
		// process all other types of expressions...
	}
}

A list of all types of expressions defined by the .NET framework can be found at MSDN. I won’t describe how to process each of these types in detail, if you’re interested in the full code please check out my ICommand implementation (available at codeplex) that has been published as part of the MVVMbasics framework!

Any way, after traversing the full expression tree we should end up with a list containing the names of all properties that are called from within the Command’s CanExecute condition! This list can then be used within the Viewmodel’s PropertyChanged event handler to force the condition to be re-evaluated.

A few thoughts about this solution:

  • Of course, working with lambda expressions has an impact on performance. Since analyzing the expression tree is done only once during Command initialization (and not each time the Command is invoked, or the condition is re-evaluated), and since most real-life Command conditions are rather simple and depend on only one or two properties, this should not affect a project’s overall performance.

    Nevertheless, you should always take into account that more complex conditions may be necessary in certain use-cases, so it might be a good idea to provide an overload to the Command’s constructor that still accepts a list of dependent properties. This allows other developers who make use of the Command implementation to circumvent the ParseExpresionTree() method in certain cases.

  • I decided to stop walking down the expression tree whenever a separate method is called. This decision is mainly based on performance considerations: It can be assumed that CanExecute conditions that are passed as inline lambda expressions won’t be too complex and therefore can be analyzed rather quickly by traversing their expression tree, while the complexity of an external method’s body (and therefore the effort necessary for analyzing the method’s contents) cannot be estimated.

    However, it might be a good idea to at least process the expressions contained in a MethodCallExpression‘s Arguments collection, since they might contain a MemberExpression that references a property which otherwise would have been omitted. For example, the Keywords property in our sample Command declaration is only referenced once as parameter to the String.IsNullOrEmpty() method – this property would have been lost!

    Again, also because of this limitation it might be a good idea to offer an overload constructor that allows to manually specify the list of dependent properties – otherwise, it would be impossible to retrieve the dependent properties if only an external method was passed as condition.

  • Finally, this approach is rather tolerant: It might find values that are actually not referenced as properties from within the given expression. This is not a problem, since those values (although being stored in the list of dependent properties) won’t appear as PropertyChanged event args and therefore won’t ever be used for comparison.

Permanent link to this article: http://www.mobilemotion.eu/?p=1424&lang=en

Feb 20

A smart ICommand implementation #3

To avoid the drawbacks of manually querying Command conditions from within the dependent properties’ setter methods as listed in the previous post, I’d like to discuss an approach that combines all dependencies within the Command initialization. The solution presented in this article is based on Thomas Mutzl’s smart command implementation, in the following (and final) blog post I’ll suggest a further improvement of this approach.

Binding conditions to Viewmodel properties:

Basically, we’d like to get rid of the Command references within the bindable properties’ declarations. Instead of defining for each property which commands depend on it, the idea is to instruct each command on which properties it depends. The command would then register to those properties’ PropertyChanged event – this way, the command is automatically informed whenever one of the properties it depends on has changed, and it can re-evaluate its CanExecute condition.

To do so, we’d need to pass a reference to the Viewmodel as well as a list of all dependent property names to each Command during initialization – our example Command as defined in part #2 would look as follows:

public DelegateCommand SearchCommand { get; set; }
 
public MyViewmodel()
{
    SearchCommand = new DelegateCommand(SearchMethod,
            () => IsLoggedIn && !String.IsNullOrEmpty(Keywords),
			this,                                               // Reference to the Viewmodel
			"IsLoggedIn", "Keywords"                            // List of all properties the condition depends on
	);
}

private string _keywords;
public string Keywords
{
    get { return _keywords; }
    set
    {
        _keywords = value;
        RaisePropertyChanged("Keywords");
    }
}
 
private bool _isLoggedIn
public bool IsLoggedIn
{
    get { return _isLoggedIn; }
    set
    {
        _isLoggedIn = value;
        RaisePropertyChanged("IsLoggedIn");
    }
}

The Command’s constructor would register to the PropertyChanged event that is provided by the Viewmodel. Whenever this event is raised, it needs to check if the source property is included in the list of registered dependent properties, an in this case it would raise the CanExecuteChanged event to signal that the condition must be re-evaluated:

public class DelegateCommand : ICommand
{
    private readonly Action<object> _action;
  
    private readonly Func<object, bool> _condition;
	
	private readonly string[] _dependsOnProperties;
  
    public DelegateCommand(Action<object> action, Func<object, bool> condition, 
			INotifyPropertyChanged viewmodel, params string[] dependsOnProperties)
    {
        _action = action;
        _condition = condition;
		_dependsOnProperties = dependsOnProperties;
		
		viewmodel.PropertyChanged += ViewmodelPropertyChanged;
    }
	
	private void ViewmodelPropertyChanged(object sender, PropertyChangedEventArgs e)
	{
		if (_dependsOnProperties.Contains(e.PropertyName))
			RaiseCanExecuteChanged();
	}
  
    public event EventHandler CanExecuteChanged;
  
    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, EventArgs.Empty);
    }
  
    public void Execute(object parameter)
    {
        if (CanExecute(parameter))
            _action.Invoke(parameter);
    }
  
    public bool CanExecute(object parameter)
    {
        return _condition == null || _condition.Invoke(parameter);
    }
}

The big advantage of this solution is that both the CanExecute condition itself and the properties it depends on are declared directly within the Command’s constructor – the property declarations stay clean and need not contain any information about the participating commands. Whenever a Command’s condition changes, only the Command’s constructor needs to be adapted.

Nevertheless, the presented approach still is far from perfect: For example, what’s rather annoying is that the dependent properties’ names are passed as string types – when changing some property’s name during refactoring, these values needs to be reworked manually. Instead, we could define a Command constructor that expects a list of expressions instead of string values – the constructor’s signature would then look as follows:

public DelegateCommand(Action<object> action, Func<object, bool> condition, 
			INotifyPropertyChanged viewmodel, params Expression<Func<object>>[] dependsOnProperties)

The constructor would need to retrieve each property’s name from this list of expressions to be able to store them as string values – this is necessary since we want to compare it with the property name passed by the PropertyChanged event handler, and this one still is of type string. Since we’re not done yet and I’ll present a different optimization approach shortly, I won’t go into details about this adaptation – if you’re interested in how the Command’s constructor could be implemented in detail, please check out Thomas Mutzl’s original article!

Irrespective of the decision whether we want to pass property references as expression or string value, there are still two aspects that can be improved:

  1. The fact that we need to pass this as a reference to the Viewmodel, and
  2. the fact that the list of dependent properties seems redundant, since the condition itself (which is defined in the same line of code, only a few characters to the left) basically contains the same informations.

While issue #1 (the reference to the Viewmodel via this) is mainly a personal preference, it can be changed easily, for example by creating an extension method to the INotifyPropertyChanged interface that returns a new instance of DelegateCommand

public static DelegateCommand CreateCommand(this INotifyPropertyChanged viewmodel, Action<object> action,
			Func<object, bool> condition, params string[] dependsOnProperties)

…which, at least, moves the reference to this to the beginning of the line:

public MyViewmodel()
{
    SearchCommand = this.CreateCommand(SearchMethod,
            () => IsLoggedIn && !String.IsNullOrEmpty(Keywords),
			"IsLoggedIn", "Keywords");
}

If you’re using a base Viewmodel class all Viewmodels within a project are derived from, the CreateCommand method can also be defined within this base class, in this case even this reference to the this keyword can be omitted.

Issue #2 is more relevant, as getting rid of the list of property names would help shorten the Command initialization significantly. On the other hand, it is a more complex task, which is why I’ve decided to deal with this topic in a separate blog post – if you’re interested in this final optimization step, check out part #4 of this series of articles!

Permanent link to this article: http://www.mobilemotion.eu/?p=1416&lang=en

Feb 17

A smart ICommand implementation #2

If we cannot rely on CommandManager in Windows Store Apps, as mentioned in the previous post, how can we manually re-query our Commands’ CanExecute conditions at the right point of time? This might sound more difficult as it really is in most cases. Let’s think of a real-life example to illustrate this:

Imagine a business application that includes, among others, a search function consisting of a text field for entering key words and a Search button. The user may only click the Search button is he or she is logged in and if some key words have been entered in the designated text field. Both login status and key words will already be represented in the Viewmodel, e.g. the text field’s content might be binding to a string property:

private string _keywords;
public string Keywords
{
	get { return _keywords; }
	set
	{
		_keywords = value;
		RaisePropertyChanged("Keywords");
	}
}

private bool _isLoggedIn
public bool IsLoggedIn
{
	get { return _isLoggedIn; }
	set
	{
		_isLoggedIn = value;
		RaisePropertyChanged("IsLoggedIn");
	}
}

Note that for simplicity reasons I use short bindable property declarations that do not check if the value has changed in the setter. In practice, you might want to use one of the convenience methods discussed in An elegant INotifyPropertyChanged implementation.

In addition, the Search button is binding to a Command that is defined using the DelegateCommand presented in the first part of this series of articles. This one specifies a condition to indicate that is shall only be active if the user is logged in and if the Keywords property contains values:

public DelegateCommand SearchCommand { get; set; }

public MyViewmodel()
{
	SearchCommand = new DelegateCommand(SearchMethod, 
			() => IsLoggedIn && !String.IsNullOrEmpty(Keywords));
}

Querying CanExecute conditions manually:

Since the SearchCommand‘s condition is based on the Keywords and IsLoggedIn properties, whenever one of those two properties changes we need to inform the View that the Command’s condition must be re-evaluated. Fortunately, the ICommand interface defines the CanExecuteChanged event which any View can register to, so we just need to raise this event. The DelegateCommand already contains a convenience method RaiseCanExecuteChanged() that checks for null and raises this event, so we can just call this method in each property’s setter:

private string _keywords;
public string Keywords
{
	get { return _keywords; }
	set
	{
		_keywords = value;
		RaisePropertyChanged("Keywords");
		SearchCommand.RaiseCanExecuteChanged();
	}
}

private bool _isLoggedIn
public bool IsLoggedIn
{
	get { return _isLoggedIn; }
	set
	{
		_isLoggedIn = value;
		RaisePropertyChanged("IsLoggedIn");
		SearchCommand.RaiseCanExecuteChanged();
	}
}

If we declare bindable properties using the custom Set() convenience method as suggested in An elegant INotifyPropertyChanged implementation #4, we could of course create an overload of this method that accepts a list of all Commands that depend on a certain property. The Set() method would then call RaiseCanExecuteChanged() on all those commands, and we could shorten the property declarations to something like the following:

private string _keywords;
public string Keywords
{
	get { return _keywords; }
	set { Set(ref _keywords, value, "Keywords", CreateCommand); }
}

private bool _isLoggedIn
public bool IsLoggedIn
{
	get { return _isLoggedIn; }
	set { Set(ref _isLoggedIn, value, "IsLoggedIn", CreateCommand); }
}

This approach basically has two disadvantages:

  • Since several commands might depend on one property, we’d need to add a params ICommand[] commands parameter to the Set() method. This, however, does not work in combination with the [CallerMemberName] attribute that is already present in the Set method’s signature, because both need to be specified as the last parameter. Therefore, as you can see in the example snippet above, we’d need to specify the property name as string which brings about subsequent problems, as discussed in An elegant INotifyPropertyChanged implementation #2.
  • In addition, it’s not easily maintainable: Whenever some Command’s condition changes, we need to browse through the declarations of all properties that are referenced in the condition, and ensure that each property’s setter includes a call to the Command’s RaiseCanExecuteChanged method.

There is in fact another approach that solves both problems by declaring all property dependencies directly within the Command’s initialization. A detailed explanation will follow in part #3!

Permanent link to this article: http://www.mobilemotion.eu/?p=1411&lang=en

Feb 13

A smart ICommand implementation #1

In my series of blog posts covering the very basics of MVVM, I presented a basic MVVM Command. At first sight, there’s not much to discuss: As the .NET ICommand interface (and its two methods Execute and CanExecute) suggests, Commands basically have two purposes:

  • Each command contains an action that it executes on request.
  • In addition, it may contain a condition that must be fulfilled for the specified action to be carried out.

The simplest command implementing the ICommand interface would look like the following:

public class DelegateCommand : ICommand
{
    private readonly Action<object> _action;
 
    private readonly Func<object, bool> _condition;
 
    public DelegateCommand(Action<object> action, Func<object, bool> condition)
    {
        _action = action;
        _condition = condition;
    }
 
    public void Execute(object parameter)
    {
		if (CanExecute(parameter))
			_action.Invoke(parameter);
    }
 
    public bool CanExecute(object parameter)
    {
        return _condition == null || _condition.Invoke(parameter);
    }
 
    public event EventHandler CanExecuteChanged;
 
    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, EventArgs.Empty);
    }
}

Note that this basic implementation also allows the creation of Commands that don’t expect parameters, as well as Commands that don’t specifiy a condition for the action to be executed, by passing null to either the parameter or the condition argument. In a production environment, you might want to add constructor overloads to do so, but I’ll omit those in this article for the sake of simplicity.

As can be seen in the code snippet above, both the action to be executed and the condition are typically passed to the Command as constructor parameters. Executing the specified action is not that thrilling since it won’t change during runtime, however the condition is a bit more tricky since its result may of course change and therefore needs to be re-evaluated under certain conditions.

In any case, the condition should be evaluated before executing the action. However, UI frameworks such as WPF visualize a Command’s CanExecute condition by enabling or disabling the user control that is bound to the Command. If a Button binds to a Command whose condition evaluates to false, for example, the button will be drawn as inactive and can’t be clicked by the user. This means that CanExecute conditions should be re-evaluated regularly. In this series of articles, I’d like to present and discuss various ways of updating MVVM Commands’ conditions.

Auto-updating conditions:

WPF features a global CommandManager class. This one keeps track of an application’s Commands and automatically re-evaluates their CanExecute conditions on certain occasions, e.g. when input focus switches from one control to another, when a list’s selected item changes, etc. In addition, you can also force it to re-query all Commands’ conditions by calling the CommandManager.InvalidateRequerySuggested() method.

There are only two drawbacks of relying on the CommandManager, of which the first one is easily solved while the second one might be a blocker for certain scenarios:

  • Out of the box, CommandManager is only aware of all routed commands existing in an application, therefore it updates only their conditions. When we’re implementing our own delegate commands (e.g., by using the code snippet posted above), we need to inform WPF that our custom command exists. This can be done easily by hooking our command’s CanExecuteChanged event to the CommandManager’s RequerySuggested event, such that every time it evaluates all routed commands, also our Command’s condition is re-queried:

    public event EventHandler CanExecuteChanged
    {
    	add { CommandManager.RequerySuggested += value; }
    	remove { CommandManager.RequerySuggested -= value; }
    }
    
  • The second (and more serious) drawback is the fact that the CommandManager class is only available in WPF, not in Silverlight (as far as I know, although there are a few custom implementations out there) and certainly not for WinRT. While this is not a problem for WPF-only applications, it makes cross-platform implementations (which is one of the big advantages of the MVVM pattern in general) impossible.

    So, what can we use as an alternative solution for re-evaluating CanExecute conditions on a regular basis? There are a few strategies that allow cross-platform Commands, read on about it in the second part of this series!

Permanent link to this article: http://www.mobilemotion.eu/?p=1385&lang=en

Jan 30

Making WPF button’s Pressed state work with touch input

The short story:

In order for a WPF Button control to trigger the Pressed VisualState when using finger interaction on a touch screen (similarly to clicking with a mouse), it seems to be necessary to completely deactivate the press-and-hold right mouse button emulation by setting the Stylus.IsPressAndHoldEnabled attached property to false.

The long story:

After all those articles covering Windows Phone and WinRT Apps, it’s time for something different. We’re currently working on a WPF project that is intended to run in fullscreen mode and be operated using finger touch events on a touch screen. Since the application does not feature any complex touch gestures but is only controlled through buttons that can be pressed, we decided to refrain from referencing a dedicated touch handling framework and instead let each button press be handled as if it was a simple mouse click.

To signal a user that a button is pressed when touching it with the finger, we implemented visual states on all buttons in the application: On the Pressed VisualState, a button changes its color to appear as a physical button that is currently pressed:

<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
	<Setter Property="Template">
		<Setter.Value>
			<ControlTemplate TargetType="Button">
				<Grid>
					<Border x:Name="ButtonBorder" Background="LightGray" BorderBrush="DarkBlue" BorderThickness="3" CornerRadius="5">
						<ContentPresenter Margin="20" />
					</Border>

					<VisualStateManager.VisualStateGroups>
						<VisualStateGroup x:Name="CommonStates">
							<VisualState x:Name="Normal"/>
							<VisualState x:Name="MouseOver"/>
							<VisualState x:Name="Disabled"/>
							<VisualState x:Name="Pressed">
								<Storyboard>
									<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBorder" Storyboard.TargetProperty="Background">
										<DiscreteObjectKeyFrame KeyTime="0">
											<DiscreteObjectKeyFrame.Value>
												<SolidColorBrush Color="DarkGray" />
											</DiscreteObjectKeyFrame.Value>
										</DiscreteObjectKeyFrame>
									</ObjectAnimationUsingKeyFrames>
								</Storyboard>
							</VisualState>
						</VisualStateGroup>
					</VisualStateManager.VisualStateGroups>
				</Grid>
			</ControlTemplate>
		</Setter.Value>
	</Setter>
</Style>

The application was developed and basically tested using common monitor and a mouse. When we connected the machine to a touch screen monitor to thoroughly test the first few screens, it turned out that the color change on currently pressed buttons – that had previously worked using mouse clicks – was gone, the button could actually be operated using finger touch events (and the command connected with it was executed), but the animation defined for the Pressed state was not considered.

The solution:

There are two things to distinguish here:

  • The button’s Click event is handled irrespective of input device, both mouse click and finger touch are forwarded to the same event handler and treated in the same way. This explains why the business logic connected with the button’s command is successfully executed independently from the visual state change.
  • The VisualState changes are triggered by dedicated mouse events: For example, the Pressed state is reached when the button’s OnMouseLeftButtonDown event occurs. The finger touch-and-hold event is usually mapped to a click with the right mouse button (when tapping on the screen and not instantly releasing the finger, Windows interprets this as right-click operation) – the OnMouseLeftButtonDown event never fires, and the Pressed state is never reached!

Fortunately, this can be fixed easily by completely disabling the right-click simulation, either for a distinct button or for the whole window / page, by setting the Stylus.IsPressAndHoldEnabled attached property to false:

<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
	<Setter Property="Stylus.IsPressAndHoldEnabled" Value="False"/>
	...
</Style>

Permanent link to this article: http://www.mobilemotion.eu/?p=1396&lang=en

Jan 22

Toggle comments bug in Xamarin Studio

I’m currently working on several Xamarin project, among others adapting the MVVMbasics framework to support the Xamarin.Forms target platform. This means I’m playing around a lot with Xamarin Studio, and today I located a minor but annoying bug in version 5.7 of the Xamarin Studio development environment:

Xamarin Studio features the useful Toggle Line Comment(s) command that can be found either in the text editor’s context menu or in the Edit > Format > menu, or invoked using the Ctrl+Alt+C hotkey. In the C# editor, this command adds a code comment (//) at the beginning of the line the cursor is positioned in, or removes an existing comment. If several full lines are selected, it adds the comment markers to the beginning to all currently selected lines.

In the XML editor, however, when several full lines are selected, the command creates an XML comment (<!– –>) that starts at the beginning of the first selected line, and reaches not only until the end of the last selected line but until the end of the line that follows the last selected one. The following two images illustrate this behavior by showing a sample XML code snippet before and after applying the Toggle Line Comment(s) command:

Short line

Short line
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

I’ve just reported this behavior to the official Xamarin bug tracking system, let’s see what they do with it. Meanwhile, it’s good to know that in the XML editor, you should always select one line less than you’d actually like to comment!

Permanent link to this article: http://www.mobilemotion.eu/?p=1400&lang=en

Jan 20

An elegant INotifyPropertyChanged implementation #4

This is the last part of a series of articles discussing an optimal implementation of the INotifyPropertyChanged event. As we’ve managed to implement a maintainable bindable property declaration by removing all string references, there are still two open questions left: How can we reduce the amount of code needed for one property declaration, thus reducing the effort in actually writing the code and at the same time making the resulting code more readable?

In a first step, let’s try to reduce the actual property declaration code to as few lines as possible! Unfortunately, we won’t ever be able to use auto-properties since we need to intercept the property’s setter method, so there’s no way to get rid of the backing field or the manual implementation of getter and setter method – however, we can shorten those! The property’s getter is already as short as possible, containing just one line that returns the backing field’s content. In contrast, the setter method is quite verbose and can surely be simplified!

Remember that, as I shortly mentioned in the first part of this article series, a typical bindable property’s setter method needs to do the following things:

  1. Compare old and new value, (to ensure PropertyChanged is only raised on actual changes),
  2. if the two are different, set the backing field’s value,
  3. raise the property’s PropertyChanged event,
  4. optionally raise other properties’ PropertyChanged events (in case some other properties depend on the current one),
  5. and optionally raise some Commands’ CanExecuteChanged events (in case some Commands’ execute conditions depend on the current property)

The first three steps are necessary for all bindable properties, the fourth one is optional. The fifth step (informing some Command that its execute condition has changed) can actually be omitted and moved to the actual Command’s implementation (I’m planning a separate article explaining this smart ICommand implementation in detail), so I’ll ignore this step for the time being.

To make the property setter shorter and more readable, we simply move all the contained code to a generic helper method that can be called from within every property declaration! I call this helper method Set(), since that describes quite well what it’s doing (and is a name as short as possible), and its signature looks like this:

protected void Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)

As you can see, we pass the backing field (by reference, since we’ll need to update it’s content!), the new value, and the property name (for raising the PropertyChanged event). The latter can be omitted to be automatically replaced by the calling property’s name, as we’ve learned in part #2 of this series.

Now we’re ready to fill in the Set method’s body to make it process all the steps listed above. First, to compare old and new value, we can not rely on type-specific comparison method (such as String.Equals(...)) any more, since the Set method shall work for all types. Instead, I suggest using the Object.ReferenceEquals method that checks whether two object instance are the same instance:

if (!ReferenceEquals(field, value))
{
	....
}

Replacing the backing field’s old value with the new one is a simple assignment, and raising the PropertyChanged event is not difficult either since we can rely on the RaisePropertyChanged method defined earlier (we just need make sure that we pass the property name explicitly this time, otherwise the PropertyChanged will be raised with a parameter that says Set instead of the actual property name!):

protected void Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
	if (!ReferenceEquals(field, value))
	{
		field = value;
		RaisePropertyChanged(propertyName);
	}
}

This implementation covers the first three (mandatory) steps listed above. In order to also take care of the fourth one (the optional), we could create an overload of the Set method that accepts an additional dependent property whose PropertyChanged event shall also be raised:

protected void Set<T>(ref T field, T value, Expression<Func<T>> dependentProperty,
                      [CallerMemberName] string propertyName = null)
{
	if (!ReferenceEquals(field, value))
	{
		field = value;
		RaisePropertyChanged(propertyName);
		RaisePropertyChanged(dependentProperty);
	}
}

(Of course, in some cases it might be necessary to raise the PropertyChanged event for multiple dependent properties, in this case we’d need another overload that accepts a collection of additional properties, but for the sake of simplicity I omit this step for now.)

One final step can be done to reduce the amount of code and at the same time make the code more maintainable: We should relocate both the RaisePropertyChanged methods and the Set methods to a separate class – let’s name it BaseViewmodel that every production Viewmodel can inherit from:

public void BaseViewmodel : INotifyPropertyChanged
{
		public event PropertyChangedEventHandler PropertyChanged;

		protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
		{
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
		}

		protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> property)
		{
			string propertyName = ((MemberExpression)property.Body).Member.Name;
			RaisePropertyChanged(propertyName);
		}

		protected void Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
		{
			if (!ReferenceEquals(field, value))
			{
				field = value;
				RaisePropertyChanged(propertyName);
			}
		}

		protected void Set<T>(ref T field, T value, Expression<Func<T>> dependentProperty,
		                      [CallerMemberName] string propertyName = null)
		{
			if (!ReferenceEquals(field, value))
			{
				field = value;
				RaisePropertyChanged(propertyName);
				RaisePropertyChanged(dependentProperty);
			}
		}
}

This way, we’ll never ever need to write those methods again, just reference the BaseViewmodel class! So our sample PersonViewmodel class looks as clean as:

class PersonViewmodel : BaseViewmodel
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set { Set(ref _firstName, value, () => FullName); }
    }
 
    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set { Set(ref _lastName, value, () => FullName); }
    }
 
    public string FullName
    {
        get { return String.Format("{0} {1}", FirstName, LastName); }
    }
}

Unfortunately, this is as far as we get. The only way to make these bindable property declarations even shorter would be the use of auto-properties (e.g., public string FirstName { get; set; }) – however, you won’t be able to pack the PropertyChanged event raising mechanism into these. With current technology (.NET 4.5, C# 6) it’s not possible to adapt a property’s setter method (and, for example, inject the RaisePropertyChanged call into it), not even using Reflection.

That said, there are in fact ways to make auto-properties bindable (there exist libraries out there that allow using Attribute-marked auto-properties), but these build on IL code instead of the C# language. Since this is kind of a different story, I’ll discuss this approach in a separate series of articles

Permanent link to this article: http://www.mobilemotion.eu/?p=1376&lang=en

Jan 13

An elegant INotifyPropertyChanged implementation #3

The previous article showed how to implicitly inform the PropertyChanged event about the changed property’s name without explicitly passing it as string value. However, there are still open questions: For example, how to raise the PropertyChanged event to indicate that another property (that depends on the current one) has changed? Or, what to do if you’re stuck with a .NET version older than 4.5 in which the CallerMemberName attribute is not available?

In this case, we still need to pass the changed property’s name to the RaisePropertyChanged method, but we’d like to not pass it in form of a string parameter in order to simplify code refactoring. The idea is to pass the changed property as lambda expression, and within the RaisePropertyChanged method parse this expression to retrieve the property’s name (its name as string type is still necessary since it needs to be included in the PropertyChangedEventArgs).

To do so, we create an overload to the existing RaisePropertyChanged method that expects a lambda expression as parameter, resolves this expression, retrieves the property’s name that is represented by the expression, and finally invokes the original RaisePropertyChanged method with this name as parameter:

protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> property)
{
    string propertyName = ((MemberExpression)property.Body).Member.Name;
    RaisePropertyChanged(propertyName);
}

What’s happening whithin this method implementation, especially in the first line that includes all the reflection magic? Let’s walk through it step by step:

  1. We’re retrieving the lambda expression’s content by calling its Body property.
  2. Since we’re expecting the whole expression to represent a property, we cast its content to type MemberExpression.
  3. To actually access the passed property, we call the resulting MemberExpression’s Member property.
  4. Finally, what we’re really interested in is this property’s name – this is stored as string type in the member’s Name property!
  5. Now, to avoid redundant code, we don’t raise the PropertyChanged event directly, and instead call the existing overload of the RaisePropertyChanged and let it do the rest.

With this method overload available within our sample PersonViewmodel, we can get rid of both string typed property references within the FirstName property’s setter:

private string _firstName;
public string FirstName
{
	get { return _firstName; }
	set
	{
		if (!_firstName.Equals(value))
		{
			_firstName = value;
			RaisePropertyChanged();               // Property name automatically filled in by the [CallerMemberName] attribute
			RaisePropertyChanged(() => FullName);  // Property referenced as lambda expression
		}
	}
}

Obviously, this approach could be used for both use-cases: To indicate that another property has changed as well as that the calling property itself has changed, since we could write the first invocation of the RaisePropertyChanged also as RaisePropertyChanged(() => FirstName); – this will still fulfill our aim of writing refactoring-friendly code since it omits string variables. You’ll even be forced to do so if you’re targeting a .NET version older that 4.5 that doesn’t support the CallerMemberName attribute. However, I strongly recommend to use the [CallerMemberName] approach whenever possible, because

  • it does not rely on reflection and is therefore much faster at runtime,
  • and (obviously) even if it seems fine to pass the changed property as lambda expression instead of string value, its even more comfortable to pass no parameter at all!

Now that we’ve managed to completely get rid of all string based property references, there are still two more open questions: The next part #4 will show how to implement the INotifyPropertyChanged interface ss short and readable as possible!

Permanent link to this article: http://www.mobilemotion.eu/?p=1370&lang=en

Jan 06

An elegant INotifyPropertyChanged implementation #2

Let’s start with the third one of the aims specified in the first part of this series of articles: Get rid of the string type parameter that passes the updated property’s name to the RaisePropertyChanged method!

.NET 4.5 introduced a new feature commonly referred to as Caller Information. This includes three attributes that may be assigned to optional parameters of any .NET method, and that represent different characteristics of the code that actually calls this specific method – the optional parameters marked with one of these attributes are replaced by the actual values at compile time. The following three attributes are available:

  • CallerFilePathAttribute (Full path of the source file that contains the caller, as string)
  • CallerLineNumberAttribute (Line number in the source file at which the method is called, as int)
  • CallerMemberNameAttribute (Method or property name of the caller, as string)

The third attribute CallerMemberName is interesting in the context of INotifyPropertyChanged: It can be used to pass the updated property’s name to the PropertyChanged event’s rasing method automatically.

Let’s take a look at the implementational details! As explained in detail in the blog post The very basics of MVVM, every class that implements the INotifyPropertyChanged interface (such as each (View-)Model class) needs to include a public event PropertyChanged, typically complemented by a convenience method to actually raise this event:

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void RaisePropertyChanged(string propertyName)
{
	PropertyChangedEventHandler handler = PropertyChanged;
	if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}

Since the CallerMemberName attribute may only be applied to optional parameters, the first step would be to turn the RaisePropertyChanged method’s propertyName parameter into an optional one:

protected virtual void RaisePropertyChanged(string propertyName = null)
{ ... }

This is perfectly valid, since – according to MSDN – a PropertyChanged event containing null as property name indicates that all properties within the Model class have changed, and the whole View must be updated.

Now, actually inserting the CallerMemberName attribute is simple – the method’s content doesn’t need to be changed:

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
	PropertyChangedEventHandler handler = PropertyChanged;
	if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}

This allows us to call the RaisePropertyChanged method without passing the calling property’s name, as from within our sample PersonViewmodel:

private string _firstName;
public string FirstName
{
	get { return _firstName; }
	set
	{
		if (!_firstName.Equals(value))
		{
			_firstName = value;
			RaisePropertyChanged();
			RaisePropertyChanged("FullName");
		}
	}
}

What happens between the lines is the following: The sample property contains two references to the RaisePropertyChanged method, the first one is missing its parameter while the second one specifies the string parameter as usual. During compile time while converting C# code to Intermediate Language (IL) code, the compiler stumbles across the first method invocation, recognizes that a parameter marked with the CallerMemberName attribute has been omitted, and inserts the calling property’s name there as string – just as if we would have written RaisePropertyChanged("FirstName");. In contrast, the second method invocation is not manipulated by the compiler since a string parameter has manually been specified, thus overriding the CallerMemberName attribute.

What’s really important in this context is to notice that there’s no reflection involved – the CallerMemberName attribute is simply replaced by the calling method’s or property’s name as string at compile time, so there’s no need to go searching for the calling object using reflection mechanisms at runtime. This implies that the [CallerMemberName] approach has no impacts on runtime performance – in fact, it’s exactly as fast as the traditional approach of manually passing the property name, since both approaches produce the same IL code!

This approach makes it needless to pass property names as string variables in the most common use-cases of the RaisePropertyChanged method: To let a property indicate that itself has changed. However, as we’ve seen in the code samples above, there are still cases where it’s necessary to manually pass string values: To indicate that another property has changed! We’ll cover this in the next part #3.

Permanent link to this article: http://www.mobilemotion.eu/?p=1361&lang=en

Dec 31

An elegant INotifyPropertyChanged implementation #1

As explained in the article series The very basics of MVVM, each (View-)Model property to be available for Data Binding in the View layer needs to raise the PropertyChanged event whenever its content changes. This is necessary to inform View classes (pages, windows, etc.) that are registered to this event about changes in the data, in order to make the View update and redraw itself.

Speaking about code, this event is typically raised directly within the property’s setter. Unfortunately, this fact makes it impossible to implement data binding properties as simple auto-properties, instead it’s necessary to create a private backing field and implement the public property’s getter and setter from scratch – and, moreover, it results in quite long setter methods: Such a property’s setter needs to execute at least three steps:

  1. Compare old and new value, (to ensure PropertyChanged is only raised on actual changes),
  2. if the two are different, set the backing field’s value,
  3. and finally raise the PropertyChanged event

A typical Viewmodel contains several data binding properties, implementing each of them as described above is repetitive and error-prone. Fortunately, there exists a variety of libraries that can help shorten those property declaration, e.g. most MVVM frameworks provide helper functions aiming at this, but I think it’s always good to know how to do things from scratch – in practice, you’ll of course let one of the established frameworks do the work for you, but wouldn’t it feel good to actually know how the black magic within these frameworks is implemented?

The aim of this blog post (and the next ones) is to show different ways of implementing the INotifyPropertyChanged in a more elegant and efficient way, explain why there are different ways at all, and discuss which approach to use for what use-case. In summary, we’re looking for an INotifyPropertyChanged implementation that

  • makes coding faster, by reducing the necessary amount of code to write,
  • makes code more readable, by reducing each property declaration to as few lines as possible, and
  • makes code more maintainable (Have you ever been annoyed by the PropertyChanged event expecting the changed property’s name as string? How on earth should someone be able to refactor code that contains property names in string variables?)

Before actually starting with the implementational issues, I’d like to point out that there are actual two different reasons for raising the PropertyChanged event from within a property’s setter. Consider the following example of a simple Viewmodel that contains three bindable properties (I’ve omitted the actual PropertyChanged event and the RaisePropertyChanged method’s implementation to shorten the code snippet):

class PersonViewmodel : INotifyPropertyChanged
{
	private string _firstName;
	public string FirstName
	{
		get { return _firstName; }
		set
		{
			if (!_firstName.Equals(value))
			{
				_firstName = value;
				RaisePropertyChanged("FirstName");
				RaisePropertyChanged("FullName");
			}
		}
	}

	private string _lastName;
	public string LastName
	{
		get { return _lastName; }
		set
		{
			if (!_lastName.Equals(value))
			{
				_lastName = value;
				RaisePropertyChanged("LastName");
				RaisePropertyChanged("FullName");
			}
		}
	}

	public string FullName
	{
		get { return String.Format("{0} {1}", FirstName, LastName); }
	}
}

The FullName property does not contain a backing field and a setter at all, since it relys on the other two properties and is just a combination of those two. Therefore it does not raise the PropertyChanged event on it’s own. Instead, both the FirstName and LastName properties call the RaisePropertyChanged() method twice within their setters:

  • Once passing their own property names as parameter, to indicate that their own content has changed,
  • and once again passing the FullName property’s name, to indicate that its content has also changed and potential View controls displaying the FullName property’s content need to be redrawn also!

We’ll see that there exist different approaches to simplify raising the PropertyChanged event for those two cases in the following articles. Let’s just step into the first one: An elegant INotifyPropertyChanged implementation #2!

Permanent link to this article: http://www.mobilemotion.eu/?p=1359&lang=en

Older posts «