Category Archives: WPF

Bing it on, Reactive Extensions! – story, code and slides

I held a presentation at UBISOFT Buchares headquarters for the RONUA local programmers user group recently as I’ve announced earlier.
Here’s the contents, step-by-step, final code and slides.

————- [scroll way down for the downloads]

I was recently tasked with rewriting an app component by leveraging Reactive Extensions. I knew little about Rx (the short form of Reactive Extensions) and all I remembered was that it has two interfaces IObservable and IObserver and it seemed dull at that time.

Basically the component enables search without needing to hit ENTER or a “Go!” button, although provides for these. After the user finishes typing an async request goes to the data store and searches for the phrase entered and fetches the results. In the original implementation the component used a lot of timers, event handlers, private fields all making up a nice spaghetti bowl of code.

Let’s do this step by step and see how our little (demo) app develops. Fire up Visual Studio 2012 and start a new WPF project (.NET 4.5 preferrably). The very next thing we’ll install Rx. Right click on the project in the Solution Explorer and select “Manage NuGet Packages” (you can also use the Package Manager Console if you like it better). Search online for “Reactive Extensions”.

In the result lists (this requires a functional internet connection) select ‘Reactive Extensions – WPF Helpers‘ (the nice thing about NuGet packages is that it automatically resolves and installs all the dependencies). Accept the license(s) (you know what’s the most common lie told these days? “I have read and accepted the terms of the license” :P ).

In our demo we will use Bing as the data store which we’ll target through our searches (sorry, Google was too difficult to setup, offered less search requests per month and no C# demo code. Thanks Google, thanks again.). In order to do this you will need a Microsoft Account (I guess we all have one these days). Go to http://www.bing.com/developers/ and then select “Search API” -> Start now (this will lead you to https://datamarket.azure.com/dataset/5BA839F1-12CE-4CCE-BF57-A49D98D29A44 ). There are paid subscriptions and a free subscription. Hit signup and go through the process (leave a comment if you are unable to go through this process).

In the end you will need to obtain the (Primary) Account Key and the Customer ID. These are available under “My Account” -> Account Information ( https://datamarket.azure.com/account ). We’ll use these later so save them. Also, don’t share them with other people because these are your credentials. Also visit “My Data” ( https://datamarket.azure.com/account/datasets ) and click on “Bing Search API”‘s “Use” link (far right, https://datamarket.azure.com/dataset/explore/bing/search ). Capture the “URL for current expressed query” : “https://api.datamarket.azure.com/Bing/Search/v1/Web“. We’ll also need these later.

Read more »

CallerMemberName – an easier way to do INotifyPropertyChanged AND MORE

In WPF, when applying the MVVM (an arhitectural pattern) we often need to implement the INotifyPropertyChanged on certain classes (ViewModel classes), which means something like this :


public class PersonViewModel : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value) return;
            _name = value;
            NotifyPropertyChanged("Name");
        }
    }

    private void NotifyPropertyChanged(string propertyName)
    {
        var evt = PropertyChanged;
        if (evt != null) evt(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

In case you’re wondering why I copied the PropertyChanged value to the local variable called “evt” and then tested it for null is that you can have race conditions, in general, triggering events (i.e.: you test the attribute value, it is not null and before you trigger it some other thread sets it to null and bang, NullReferenceException when you trigger it). More details on this CodeProject.

The next step is to pull the NotifyPropertyChanged method and PropertyChanged event into a base class (let’s call it ViewModelBase) and you’ve eliminated redundancy between several ViewModel classes.

The not-so-nice part is having the call to NotifyPropertyChanged stringly-typed. That means that if later you rename (via Visual Studio or ReSharper) the Name property to “FullName” the call will still pass “Name” as the argument.

Some blog posts around the web show how you can use a Func to make it type-safe (refactor safe etc).

More or less they’re doing the same thing :


public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(Expression<Func<object>> propertyAccessor)
    {
        var evt = PropertyChanged;
        if (evt == null) return;
        var propertyName = propertyAccessor.GetName();
        evt(this, new PropertyChangedEventArgs(propertyName));        
    }
}

public static class Utils
{
    public static string GetName(this LambdaExpression expression)
    {
        MemberExpression memberExpression;
        if (expression.Body is UnaryExpression)
        {
            var unaryExpression = (UnaryExpression)expression.Body;
            memberExpression = (MemberExpression)unaryExpression.Operand;
        }
        else if (expression.Body is MemberExpression)
        {
            memberExpression = (MemberExpression)expression.Body;
        }
        else
        {
            return null;
        }
        return memberExpression.Member.Name;
    }
}

This is definitely nicer, not-redundant and type-safe. It does have the drawback of having some runtime performance penalty associated with the reflection of the expression. You could cache the property name string in a private field but then you’d have to write more code in the ViewModel classes which would… suck. In practice this performance penalty is negligible so you can just ignore this.

Then came .NET 4.5 and among other improvements a new mechanism has been introduced : CallerMemberName.

Historically some folks tried to get programatically the name of the caller method by inspecting the StackTrace (for example using System.Environment.StackTrace) but this is prone to errors since in Release mode the compiler could eliminate some methods by inlining them and you’ll be screwed. Plus the penalty would be higher than reflecting an expression.

The new mechanism in .NET 4.5 is type-safe, has no runtime performance penalty and it’s more elegant. Here’s how you can use it :

public abstract class ViewModelBase : INotifyPropertyChanged
{
    protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var deleg = PropertyChanged;
        if (deleg != null)
        {
            deleg(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class PersonViewModel : ViewModelBase
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value) return;
            _name = value;
            NotifyPropertyChanged();
        }
    }
}

I’ve recently built a very small GuidGen utility (which as the name implies generates GUIDs, copies it in the Windows Clipboard and stores a history of past generated GUIDs). You can browse some of the code and check out the project.

Much nicer, isn’t it?

Funny thing, this new mechanism can be used for non-UI tasks. For example if you have a project that uses and RDBMS and you use stored procedures. Let’s say you have one method in a repository class for each stored procedure, and even more, the method’s name matches the stored procedure’s name :


public VerificationResult VerifyUser(VerificationData verificationData)
{
    if (EmailValidator.IsEmailInvalid(verificationData.EmailAddress)) throw new FormatException("emailAddress");

    var result = CreateNewCommand("VerifyUser").GetEnumResult<VerificationFailReason>(
        CreateEmailAddressParameter(verificationData.EmailAddress),
        CreateUniqueIdentifierParam("@VerificationCode", verificationData.VerificationCode));

    return new VerificationResult(result);
}

Observe on line 5 how the call to CreateNewCommand passes a string which matches the current method’s name. This can also be simplified (and become refactor-safe) using the new CallerMemberName mechanism.

So you can’t really say that CallerMemberName is useful only for UI tasks :)

WPF default binding format culture

WPF formats non-string objects to a string using a fixed/hardcoded culture (en-US) regardless of the current culture (as in Thread.CurrentThread.CurrentCulture / CultureInfo.CurrentCulture).

Suppose you have a simple DataContext (ViewModel) like so :

public class Data
{
    public DateTime Now 
    { 
        get 
        { 
             return DateTime.Now; 
        } 
    }

    public string NowText 
    { 
        get 
        { 
              return DateTime.Now.ToString(); 
        } 
    }
}

Binding an instance of `Data` to a view, with two TextBlocks each of which using ‘Now’ and ‘NowText’ respectively will yield different results if your CurrentCulture is NOT en-US.

Working on an internationalizable WPF app I’ve found out this sad truth. I don’t fully understand why this happens but I’ve found a way to “fix it”.

Somewhere before any piece of UI is shown on the screen (for example in App.xaml.cs in ApplicationStartup) just place this little piece of code :

FrameworkElement.LanguageProperty.OverrideMetadata(
  typeof(FrameworkElement),
  new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

It sets for any FrameworkElement (TextBlock and Label are included) the formatting culture to the current culture. Of course you might need to change it again if the current culture changes (for example an on-the-fly UI language changes).

WP Like Button Plugin by Free WordPress Templates