Simplifying the implementation of INotifyPropertyChanged

Everyone that has written software using WPF or Silverlight recognize the amount of boilerplate code needed to define bindable properties. I dont know you, but to me it sucks to have simple properties with only a getter and a setter looking like this:

        private int myProperty;
        public int MyProperty
        {
            get { return myProperty; }
            set
            {
                myProperty = value;
                this.Notify("MyProperty");
            }
        }

Several other ideas have been implemented in frameworks like Caliburn and MVVM Light where we gain typesafe and refactoring friendly property notification using lambda expressions. A very clever trick I might say. However, IMHO the property definition syntax is still unnatural and unclear. In short a mess :) .

        private int myProperty; 
        public int MyProperty 
        { 
            get { return myProperty; } 
            set 
            {
                myProperty = value; 
                this.Notify(() => this.MyProperty); 
            } 
        }

A potential partial solution to this problem came with C# 4.0 with its ExpandoObject or dynamic objects in general. With them we can construct a very simple syntax at the expense of tying ourselves to a base class through inheritance (nothing we are not doing anyway with almost any INotifyPropertyChanged solutions).

        public string MyProperty 
        { 
            get { return (string)this.Storage.MyProperty; } 
            set { this.Storage.MyProperty = value; } 
        }

That is achieved through the following base class definition:

    public class SimpleNotifyPropertyChangedBase : INotifyPropertyChanged 
    { 
        public event PropertyChangedEventHandler PropertyChanged = (s, a) => { }; 

        protected dynamic Storage { get; private set; } 

        
        protected SimpleNotifyPropertyChangedBase()        
        {            
            Storage = new ExpandoObject();            
            var asNotificable = (INotifyPropertyChanged)Storage;            
            asNotificable.PropertyChanged += (sender,arg) this.Notify(sender, arg);        
        }        
        
        protected void Notify(object sender, PropertyChangedEventArgs args) 
        { 
            PropertyChanged(sender, args); 
        } 
    }

This base class is actually a simple implementation that do not support almost any of the features that advanced frameworks like Caliburn.Micro or MVVM Light provides but it is simple enough to demonstrate how to implement it in there too.

On the practical side, the downside we found of using an ExpandoObject is that all properties must be defined prior to use them (in the constructor). Even though, that requirement could be easily lifted reimplementing our own ExpandoObject with a DynamicObject and returning default(T) if the property is not found; the exception is very useful as it allows to discover potential defects in our code.

Hope it is of use,
Happy Coding!!
@federicolois

Debugging your TV – Or the Samsung P2470HN HDMI cable doesn’t work problem.

When you have been working as a programmer for so many years, you debugging attitude just keep creeping out in the most mundane real-life situations. A couple of weeks ago I succumbed to my wife and bought an LCD TV. Yes, it’s been at least 6 years I do not sit to watch air TV (not that I am missing much here in Argentina). Anyways, as a computer junkie first step after hanging it into the wall was, you bet, connect my laptop to watch some online series. 

Man, as always reality kicked in, what was supposed to be the easiest thing to do, just ended up being a remainder of how a very simple uncontrolled variable can kill your users experience.
 
That’s where debugging attitude kicked in, either the HDMI cable or the TV are faulty (or worse both of them :S). 
Tried the HDMI cable on another device, and it worked… damn the TV is faulty I though. So I head back to the retail store and brought a new one, so after an hour or so, I was back with a new TV, I hanged it and guess what. IT DIDN’T WORK!!!
That’s where debugging attitude kicked in. Later that day I was going on vacations to my parents house. It turns out my father is a technology geek, in fact, I used to say when someone needed to test a computer component that I was sure there was stock of replacement parts at home. So I packed up the HDMI cable and my laptop for a ‘quick’ test.
 
Quick test, the laptop was fine, it worked on any TV set at home. The cable was too. It turns out the TV was actually faulty, but in a very different way!!!
 
Back at home after vacations, I exchanged a cable with my father, and didn’t work either. Scrap the cable incompatibility hypothesis. I hadn’t many hypothesis left. So I took the TV, the cable and the laptop for a ride to my brother-in-law house, there we setup the TV with its feet and guess what? Holy crap, it worked, not only with my brother-in-law devices, it worked with my laptop too!!!
 
The debugging spider sense started tingling as something fishy was actually happening. Doing an step by step: do one action, try if it works, do another action, try if it works I hanged the TV to the wall.
 
Long story short, the TV set has a design flaw that cause the HDMI jack to move out of position when you screw it to the wall mounting bracket. The solution is very simple and obvious (after you know about it), the bottom holes only works as support to keep it leveled, so do not screw them completely. Your mileage will vary but start unscrewing until you find the sweet spot; where you can actually move the TV around (if in an adjustable tilting wall mounting bracket) and still have HDMI connection.
 
Let me know if that helps you, as I couldnt find any solution online to this particular problem.
 
 

How to link ITextDocument with an IVsHierarchy item.

When mixing code between Visual Studio 2008 and Visual Studio 2010 sometimes we need functionality that has been replaced in the new SDK, and it is ok. However, sometimes the new API do not provides clearly what you need and you have to resort to use older APIs. Linking IVsHierarchy objects from the 2008 APIs with the ITextDocument from the 2010 API is just one of those cases.

In this blog post I will show the way I found to do it, it may not be the best, but at least works :)

First you will need this 2 services:

        [Import]
        private ITextDocumentFactoryService textDocumentFactory;

        [Import]
        private IVsEditorAdaptersFactoryService adaptersFactory;

You will also need a RunningDocumentTable

#region Implementation of IPartImportsSatisfiedNotification

private RunningDocumentTable runningDocumentTable;

void IPartImportsSatisfiedNotification.OnImportsSatisfied()
{
   var serviceProvider = ServiceProvider.GlobalProvider;
   this.runningDocumentTable = new RunningDocumentTable(serviceProvider);
}

#endregion

I have created a HierarchyItem to isolate the needed functionality but works the same if you have the IVsHierarchy and the ItemId.

public bool TryGetTextDocument(HierarchyItemIdentity identity,
                               out ITextDocument document)
{
   foreach (var documentInfo in runningDocumentTable)
   {
      if (documentInfo.ItemId == identity.ItemId &&
          documentInfo.Hierarchy == identity.Hierarchy)
      {
         var legacyBuffer = documentInfo.DocData as IVsTextBuffer;
         if (legacyBuffer != null)
         {
            var buffer = adaptersFactory.GetDataBuffer(legacyBuffer);
            if (buffer != null)
            {
               ITextDocument result;
               if (textDocumentFactory.TryGetTextDocument(buffer, out result))
               {
                  document = result;
                  return true;
               }
            }
         }
      }
  }

  document = null;
  return false;
}

public bool TryGetTextDocument(HierarchyItem item, out ITextDocument document)
{
    return TryGetTextDocument(item.Identity, out document);
}

Voilá, it returns the ITextDocument. The shortcomings of the approach is that you have to checkout every single document opened in the RunningDocumentTable to do it.

Greetings,
Federico