Skip to content

INotifyPropertyChanged, the Anders Hejlsberg Way

Back in September I was watching the Build session that Anders Hejlsberg was giving on the Future directions for C# and Visual Basic and something small but interesting stood out to me in the demo code he used.

We’re all pretty used to the standard boilerplate implementation of INotifyPropertyChanged that goes like this:

public event PropertyChangedEventHandler PropertyChanged;
 
private void NotifyPropertyChanged(String info)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}
 
private string companyNameValue = String.Empty;
public string CompanyName
{
    get { return this.companyNameValue; }
    set
    {
        if (value != this.companyNameValue)
        {
            this.companyNameValue = value;
            NotifyPropertyChanged("CompanyName");
        }
    }
}

The above code is taken directly from the MSDN article on “How to: Implement the INotifyPropertyChanged Interface“. What jumped out at me in Anders code, was that he was doing the check for equality in the helper method and not the property itself. The thought of doing this had crossed my mind before, but how could you create a method that could check for equality for any given type?

Enter the EqualityComparer<T>.Default property.

Using the Equals() method on EqualityComparer<T>.Default we can now create a generic method that compares the equality of two instances of any give type. This gives rise to the following INotifyPropertyChanged implementation that Anders used in his session:

public event PropertyChangedEventHandler PropertyChanged;
 
private void SetProperty<T>(ref T field, T value, string name)
{
    if (!EqualityComparer<T>.Default.Equals(field, value))
    {
        field = value;
        var handler = PropertyChanged;
        if (handler != null)
        {
          handler(this, new PropertyChangedEventArgs(name));
        }
    }
}
 
private int unitsInStock;
public int UnitsInStock
{
    get { return unitsInStock; }
    set 
    { 
        SetProperty(ref unitsInStock, value, "UnitsInStock");
    }
}

This not only reduces the property set implementation down to 1 line in most cases, but sets up a Pit of Success for properly implementing INotifyPropertyChanged in a class/subclass’s properties.

Nice.

(Bonus points for anyone who realized the current MSDN example code isn’t thread safe and contains a Race Condition.)

WinMerge: Not Quite Dead Yet

Every few months or so I go looking for another free diff tool that I like as much as WinMerge (usually in vain) since WM hasn’t released a new version in over 2 years. WinMerge 3, while having been in planning for almost as long, still hasn’t seen any real development traction.

Today however, I was surprised to stumble across a fork of the WinMerge 2 code base that seems to be in active development under the name of WinMerge 2011. There have been a couple of releases so far and the developer seems to be one of the WinMerge developers (Jochen Tucht) as they have commits in the official WinMerge SVN repository.

By all appearances this seems to be a promising development and I hope the developer keeps with it. WinMerge has been my favorite diff/merge tool for quite some time with only P4Merge giving it competition.

You can download the latest version of WinMerge 2011 from here: https://bitbucket.org/jtuc/winmerge2011/downloads

WPF Tools

Went in search of new WPF tools today to support some debugging/performance work I was doing in a large WPF application. I was pleasantly surprised to come across a few new ones that I wasn’t aware of.

These are the WPF tools that I know about and use on a periodic basis:

Free Tools:

  • Kaxaml

    Kaxaml is a lightweight XAML editor that gives you a “split view” so you can see both your XAML and your rendered content (kind of like XamlPad but without the gigabyte of SDK).Kaxaml is designed to be “notepad for XAML.”

    It’s supposed to be simple and lightweight and make it easy to just try something out.

    It also has some basic support for intellisense and some fun plugins (including one for snippets, one for cleaning up your XAML and for rendering your XAML to an image).

  • Pistachio

    Pistachio is a utility I created with fellow Infragistics VDGer Tim Hussey. It’s pretty simple really, you just open a .csproj file with Pistachio and it identifies all resources defined within the project, then shows you which of those resources are used and where they’re used.

  • Snoop

    “Snoop … the WPF utility by Pete Blois and now maintained by Cory Plotts that allows you to spy/browse the visual tree and change properties … amongst other things.

  • WPF Inspector

    WPF Inspector is a utility that attaches to a running WPF application to troubleshoot common problems with layouting, databinding or styling. WPF Inspector allows you to explore a live view of the logical- and visual tree, read and edit property values of elements, watch the data context, debug triggers, trace styles and much more.

  • WPF Performance Suite

    The WPF Performance Suite enables you to analyze the run-time behavior of your WPF applications and determine performance optimizations that you can apply. The WPF Performance Suite includes performance profiling tools called Perforator and Visual Profiler.

Paid Tools:

  • Mole 2010

    Mole is a debugging tool for .NET developers.  It can be opened in Visual Studio 2010 while you are stepping through your source code after hitting a breakpoint.

    Mole was implemented as a custom debugger visualizer so that you can easily use it just like any other visualizer available in Visual Studio.

    With it you can navigate object graphs, view collection data, inspect visual elements, drill into data bindings, sort and filter object properties, compare object snapshots, and more.

Quick and Easy Google (or Bing) Web Search in Visual Studio

Here is a quick and easy way to add a Google (or Bing) Web Search link to the context menu in Visual Studio:

- Open the Visual Studio macros IDE by navigating to Tools –> Macros –> Macros IDE (or pressing Alt+F11).

- Right click on “MyMacros” and select Add New –> Add New Item.

- Select the Module template, name the module “Search”, and click Add.

- Paste the following code directly before the “End Module” line:

Sub Search()
    Dim strUrl As String
    Dim selection As TextSelection = DTE.ActiveDocument.Selection()
    If selection.Text <> "" Then
        strUrl = "www.google.com/search?q=" + selection.Text
        ' strUrl = "www.bing.com/search?q=" + selection.Text
        DTE.ExecuteCommand("View.URL", strUrl)
    Else
        MsgBox("Select Text first to Search")
    End If
End Sub

- (Optional) If you prefer to use Bing for your search, uncomment the Bing line and comment out the Google line.

- Your macro editor window should now look something like this:

- Save and close the Macro Editor window and IDE.

- Right click on the Visual Studio toolbar and select Customize.

- Under the Toolbars tab, check the Context Menus option and the switch to the Commands tab.

- Select the Macros Category, and then select the “MyMacros.Search.Search” macro.

- Drag the selected macro onto “Editor Context Menus” -> “Code Window” and then drop it where you want it in the context menu (I place mine below the Paste command).

- Right click on the new context menu item and change it’s name to “&Web Search”.

- Click close on the Customize window.

- You are now done! If everything has gone according to plan, when viewing a source code file you should now see a new context menu item that will do a web search on any selected text when you click it:

Automatically Cancelling a Failed Build in Visual Studio

Stumbled across this little tip on how to automatically cancel a build in progress after getting an error. You normally have to wait for visual studio to try to finish building all of the remaining projects before getting a chance to fix an the issue and this can take a few minutes if you have a lot of projects in your solution.

Step 1: Open the Visual Studio macros IDE by navigating to Tools –> Macros –> Macros IDE.

Step 2: Double click on “MyMacros” and then on “EnvironmentEvents”. You should now be looking at a VB code editor window.

Step 3: Paste the following code directly before the “End Module” line:

Private Sub BuildEvents_OnBuildProjConfigDone(ByVal Project As String, ByVal ProjectConfig As String, ByVal Platform As String, ByVal SolutionConfig As String, ByVal Success As Boolean) Handles BuildEvents.OnBuildProjConfigDone
 
    If Success = False Then
        DTE.ExecuteCommand("Build.Cancel")
    End If
 
End Sub

Step 4: Save and close the Macro Editor window and IDE.

All done!