Archive for March, 2009

Strongly typed databinding

Monday, March 23rd, 2009

Databinding proves to be very useful in some cases, but often turns out to be a maintenance nightmare. Since it requires strings with the property names to be passed as parameters of the Binding object. When the class, where a textbox is binded to, changes over time, so do property names. But since these property names are passed around as a string, they do not raise compile errors, causing unexpected behaviour of the application.

Here’s how you can make these bindings strongly typed, causing compilation errors if the property name of a class would change. Imagine we would like to bind a textbox to the Name property of the Person class, here’s the function that is going to help us. This function has a lambda expression returning a string and receiving a Person as parameter.

public string GetPropertyName(Expression<Func<Person, string>> propertySelector)
{
   MemberExpression memberExpression = propertySelector.Body as MemberExpression;
   MemberInfo propertyInfo = memberExpression.Member;
   return propertyInfo.Name;
}

The original binding code would like this, notice the “Name” string.

m_TextEditPerson.DataBindings.Add(new Binding("Text", m_Person, "Name"));

Here’s the new binding statement.

m_TextEditPerson.DataBindings.Add(new Binding("Text", m_Person, GetPropertyName(x => x.Name)));

Load event not fired when using the WebBrowser control

Monday, March 16th, 2009

Today I had to add a way so that a webpage could be displayed with each form in a WinForms application. Doesn’t sound that hard now does it? We’ve developed our own little MVC/MVP framework, so in order to enable this behaviour I just had to create a usercontrol, throw a webbrowser control on it, some logic and done. Our framework automatically detects the control and the end user can add these controls at run time to any form he wants.

The logic I had added to the control detected if a certain file had been clicked, since these had to be handled by the application and not by the webbrowser, really straightforward stuff. In the load event of the control I registered to the necessary events which would trigger my code. The only problem being that the load event was never fired. I looked at my code again, maybe 20 lines or so including brackets and braces, and didn’t see anything wrong with it. I then looked to some other controls  my colleagues and I had already written in the past to see if I did something wrong but couldn’t see any big difference. Time for some debugging!

With breakpoints all over the place it was clear that the constructor of my form and presenter was being called and the event subscription was being done but the Load event somehow was never triggered. I went over and over the code again and again but really couldn’t get my head around this. Why on earth wasn’t the event being fired. I even went away from the compiler generated properties back to the old fashioned getters and setters with a field just to make the code look more like all the other controls but nothing worked.

Until I removed the webbrowser control from my usercontrol. Now all of a sudden my load event was being fired, the culprit was found!

So somehow when you use the webbrowser control, your load event, and who knows what else, is fubar. I only found one usable search result on the internet, here. And the workaround mentioned works like a charm, make your webbrowser control invisible until after the load event :-) . Well in my case the presenter calls NavigateToUri(uri) on my view and in that method I set the visibility of the webbrowser to true. Smells like a bug to me but at least now it’s working, too bad it took 4-5 hours.