Monday, December 29, 2008

Adventures while building a Silverlight Enterprise application part #2

In the previous episode we've looked at the requirements for our enterprise application and to some of the paths we've selected to solve some of the challenges we face. In this episode I wanted to give you more of an insight into our approach of tackling a kick-off into this project.
I know you people are craving for more technical stuff, but I found the following important enough to bug you with it.

Project organisation
The first thing that needs to be done to get any team to work is to get organized. This may seem obvious but this step is usually missed, skipped or otherwise ignored. We planned some moments of conversation for the team members, the first being every morning, take about 5-10 minutes to discuss what everybody is doing, so nobody gets into eachothers way and we also make sure everything we wanted to get done is being done.

The second moment of conversation is on a weekly basis. In this weekly meeting we can take decissions we need to take. To make this a smoother process, we take a few steps around this:
  1. Identify the need for a decission on some topic or question
  2. Apoint someone to write up a short proposal on the subject
  3. Make sure everyone gets and reads the proposal before the next weekly meeting
  4. Discuss the document during the next meeting
  5. Make any changes needed
  6. Approve the proposal, giving it a final status

The reason for this approach lies in the culture of our team. By writing a proposal we can keep our discussion on topic a little easier and also make sure that something is in print, that we can refer to at a later time.

Writing the book on it

Another thing that had to be done, was putting up some new coding standards. As a historical left over, coding standards were a bit out of date. Also as this is obviously our first enterprise application in Silverlight, some standard on XAML code and the coupling with the code behind and the services involved, would be a good idea. And a final subject we had to tackle was the layout of our TFS project. I won't bother you with all the details here, but if you have any specific questions, I'd be happy to answer them.

Startup

To actually get our project started we wanted to build a small sample of the application, containing some technical hotspots, but also some example code for the rest of the project. We will discuss this code after it's completion and revise it as needed, before moving production into full swing.

We identified the following topics to be a part of this first startup code:

- Security: Communicating with our security service and making sure the client can be authenticated, buiding the autorisation part of it, etc.

- Scalability: Loading multiple XAP's on the fly, testing performance degradation as the amount of code increases

- Multi language: Having the resource based multi language technology up and running

- Easy high volume data input: Build a module that allows for this

And besides this we also needed to include some standard modules, that would demonstrate how to build a module. Later on, this will evolve into a manual we can give new team members, for a running start.

Next time we will have a look at some code, that we build into this startup project. Please let me know what you think about this series and if there are any specific topics you would like to read about.

Wednesday, December 17, 2008

Highlighting databound information in Silverlight

As I was playing around with the Live Search SDK, to investigate integration in different applications, I ran into this issue. I wanted to display bound data and highlight it as well. I started digging and couldn't find a feasible solution on the web, so I came up with my own.

Let me start with a screenshot of the finished (well, sort of :-)) product:
What you are looking at is basically a textbox to input a query, a listbox to display the titles with highlights and a textblock to display some status information.
The highlighting information is supplied by Live search. It surrounds any term that needs highlighting with some special characters, one for the start and one for the end.
I figured that to get the highlighting, I would use a textblocks inlines property and add different runs for non-highlighted and highlighted text. The questions remained, when and where? My first order of business was to get the listbox to display data and I would figure it out later.
Here is the XAML for the listbox:

<ListBox x:Name="ResultsListBox" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<search:HighlightTextBlock Text="{Binding Title}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

As you can see I decided to use a usercontrol I would work on. The reason I used a usercontrol and not just derive from the TextBox is pretty straight forward, the TextBox class is sealed (Why, Microsoft, Why?!).
So a simple usercontrol that wraps the TextBox, is my starting point. The XAML for this is so easy that I haven't posted it here (Cause you are all an intelligent bunch, right? ;-) )

Next thing was to get the text into the textbox trough databinding. I simply added a dependency property to the user control. The code is largely generated from the snippet for it (propdp) and looks like this:

public string Text
{
get
{
return (string)GetValue(TextProperty);
}
set
{
SetValue(TextProperty, value);
}
}

// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(HighlightTextBlock), new PropertyMetadata(string.Empty, TextPropertyChanged));


The alert reader may have spotted the extra parameter in the PropertyMetadata constructor at the end here. It points to an eventhandler that will handle the actual highlighting as our textproperty is changed.
The reason for this, in short, is that whenever databinding happens, the actual property setter is never used. Instead the SetValue method is called with the dependency property object. So the only insertion point for custom code is in an eventhandler attached to the dependency property. A better explanation can be found in this great article by Bryant Likes.


So here is the code I use to highlight my text and display it in the wrapped TextBox control:


private void SetText(string value)
{
innerTextBlock.Inlines.Clear();

string remainder = value;
while (remainder.Contains('\uE000'))
{
int highlightStart = remainder.IndexOf('\uE000');
int highlightEnd = remainder.IndexOf('\uE001');

string beforeHighlight = remainder.Substring(0, highlightStart);
Run beforeHighlightRun = new Run();
beforeHighlightRun.Text = beforeHighlight;
innerTextBlock.Inlines.Add(beforeHighlightRun);

string highlight = remainder.Substring(highlightStart + 1, highlightEnd - highlightStart - 1);
Run highlightRun = new Run();
highlightRun.Text = highlight;
highlightRun.FontWeight = FontWeights.Bold;
innerTextBlock.Inlines.Add(highlightRun);

remainder = remainder.Substring(highlightEnd + 1);
}
Run finalRun = new Run();
finalRun.Text = remainder;
innerTextBlock.Inlines.Add(finalRun);
}

private static void TextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
HighlightTextBlock textBlock = d as HighlightTextBlock;
if (textBlock != null)
{
textBlock.SetText(e.NewValue.ToString());
}
}

So whenever the Text property of my usercontrol is changed, it calls the SetText method, which in turn processes the set value into a Inlines collection, based on the provided highlighting information.

There are some obvious improvements to this code, like providing a starting and closing character property and some style to apply for highlighting, but you get the picture.

I hope this was another helpful article. Please let me know what you think about it and if you have any questions, I'm always happy to help. The comment box is waiting for you.

Tuesday, December 16, 2008

Adventures while building a Silverlight Enterprise application part #1

At the moment our team is in the start up fase of building a complete enterprise applications user interface in Silverlight. As it goes, we obviously run into some challenges and find out things. This series of articles is aimed at sharing our experiences with you, so you may avoid pitfalls, and maybe even get some inspiration from our approach.



In this first installment we would like to have a look at some of the general requirements for our application and how we aim to tackle some of those.



Requirements

The following generic requirements are part of our application:


  • Secure! This is a very important requirement for our customers, as data stored is sensitive information

  • Scalable. We will provide our application to very different users that will sometimes only use a small part of the application. They will not accept a high load for a small amount of functionality.

  • Multi language. We have to support both English and Dutch in the user interface.

  • Maintainable. It may sound obvious, but our application changes several times a year.

  • Reusable. Again, this may sound obvious, but in our case, parts of the application may be reused in portals.

  • Easy high volume data input. Some of the users need to be able to quickly enter large amounts of data.

As you can see, challenges enough! Also, some performance requirements were put down, based on ASP.NET, for loading certain parts of the application.


Right now we would like to take a look at one part of the solution we used: dynamically loading XAP files.


Dynamically loading XAP files


By applying this well documented technique to our application we expect to fill in at least part of the following requirements:



  • Secure; As our application is broken down into different parts, based on different functional roles, we only load part of the application based on access rights. So a large portion of code that a user has no access to is not loaded.

  • Scalable; As our application is broken down into different parts, it is easier to scale by adding a new part in a separate XAP file.

  • Maintainable; As we are working with a team of people, having multiple projects makes it easier to maintain and deploy.

  • Performance; This is our main reason to have multiple XAP files. We don't expect to reach our performance goals, if we would use a single XAP file. By only loading XAP files as we need them, we expect to have better performance at application start up and have a smaller footprint of the client (thus better performance).

It also raised some questions that we had to answer:



  • Security; We had to pass the security context of the user between applications. Initially we planned to also use multiple pages, thus we would have to pass this context from page to page in a secure way. We decided to have one outer application that is in charge of security context and by using an interface in the loaded modules, it can optionally pass this context to the module.

  • Reusable; As it stands, parts of our application are reused trough out different XAP files. This called for a good strategy around using Silverlight Class Libraries and User Controls. We expect this to be a continuous process, trough out building the application.

This first installment didn't contain much technical stuff, I know, but I hope it gave you some insight as to what challenges may arise when you use Silverlight 2 for building an enterprise application. I also hope that this series will show you that Silverlight 2 is actually very suitable for this purpose. Read the next post here.


If you have any questions, thoughts, suggestions, etc. please leave me a comment below. I'm always happy to read and reply to any of you.

Wednesday, December 10, 2008

Storing Silverlight DataGrid settings

Don't you find it annoying whenever you use an application with some kind of datagrid, that you can resize en reorder your columns in and the next time you use your application, the changes you made are lost? I know I hate it and I know my users are annoyed by it. This made me decide to find a way to store this information for my users and restore the settings whenever the user comes back.

As a start point I used the example code from an earlier article you can find here. I'm keen to store at least the width of each column and the order of the columns within the grid. To start this off I build a custom class to hold this information:

public class ColumnSetting
{
public int DisplayIndex { get; set; }
public int Index { get; set; }
public double Width { get; set; }

public ColumnSetting()
{
}

public ColumnSetting(int displayIndex, int index, double width)
{
DisplayIndex = displayIndex;
Index = index;
Width = width;
}
}


The next step is to have a collection of these and fill them. This begs the question, when? The moment of storing your information is key in this process. Obviously this is very dependent on your requirements. To keep it simple I used only the ColumnReorderd event on the grid. Later on I might expand this to more appropriate events.

Next is the building of code that creates a collection of the ColumnSetting class I've created, so the information is stored. Here is the first part of the method that takes care of saving the settings:

private void SaveGridLayout()
{
List<ColumnSetting> settings = new List<ColumnSetting>();
for (int index = 0; index < CarGrid.Columns.Count; index++)
{
DataGridColumn column = CarGrid.Columns[index];
ColumnSetting setting = new ColumnSetting(column.DisplayIndex, index, column.ActualWidth);
settings.Add(setting);
}


As you can see I use a generic list of ColumnSetting objects to collect the information. The columns DisplayIndex gives me the relative location in the grid, which is separate from the location in the Columns collection. The ActualWidth obviously gives me the width of the column.

Next question is, where should we store this information? Again this really depends on your requirements. Do users log on to your system and do you want to have these settings based on the user? Or do you want these settings based on the client as well? In this case I decided to go with the last, because this would allow me to play with Isolated Storage, which I haven't used before.
Some info on how this will work. Every user has his or her own Isolated Storage on the client PC, so depending on what user account is used to log on to the PC and depending on which PC there are settings. If users moves from one PC to another they will not have there settings available.

So how do we store the info then? Here is the code:


IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;

if (!appSettings.Contains("carGrid"))
{
appSettings.Add("carGrid", null);
}
appSettings["carGrid"] = settings;

As you can see, my first action is to get a shorter reference to the ApplicationSettings object. Each Silverlight 2 application has one ApplicationSettings object. Based on domain there can also be shared settings in the SiteSettings object, but in this case ApplicationSettings is the obvious choice.
As someone might very well be working with your application on this client for the very first time, we need to first create a settings entry in the appSettings collection, but only if it doesn't already exist. Next we can simply set our settings into the entry that was created earlier.

So now our settings are stored and we want to load these settings into the grid at load time. The first thing I tried was to do this in the Loaded event of the user control... and it failed. This is because you can not set the DisplayIndex as a result of a change to the DisplayIndex, which happens when you use the loaded event. As is documented by Microsoft this will result in an InvalidOperationException.
I decided that a good event would be the datagrids LayoutUpdated event. To prevent the settings being loaded every time this event is triggered, I simply keep track of this with a boolean field.

The loading of the actual settings is done like this:


private void LoadGridSettings()
{
IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;
if (appSettings.Contains("carGrid"))
{
List<ColumnSetting> settings = appSettings["carGrid"] as List<ColumnSetting>;
if (settings != null)
{
foreach (ColumnSetting setting in settings)
{
DataGridColumn column = CarGrid.Columns[setting.Index];
column.DisplayIndex = setting.DisplayIndex;
column.Width = new DataGridLength(setting.Width);
}
}
}
}

As you can see, if any settings are available then they are loaded in the datagrid. Note that you obviously can't set the ActualWidth property (as it is read only), so you simply set the Width property.

I hope this article was useful to you. Please leave me a comment to tell my what you think about it, ask me any questions, or suggest any topics and I will be grateful.

Wednesday, December 3, 2008

The TextBlock Inline property in Silverlight 2

I was testing with this dynamic conversion tool I've been working on when I ran into one of those moments of complete confusion about this regular expression I had to evaluate. The Regulator didn't provide me with any insight and responded differently from the actual .NET implementation (anyone any thoughts on how that is possible?).

To get a better grip on things, I decided to build a small tool for testing regular expressions myself and as I'm always looking for a good, or less then good, excuse for using Silverlight 2, I decided to use it as my UI. I figured it would be cool to have any matches in my input highlighted on the fly, so I dove into it with the following result:



So how does this relate to the TextBlock's inline property?
Well it is used twice in this application and it may not be as obvious to everyone.

Highlighting text in Silverlight without the use of any third party controls, is different from anything we're used to in either HTML, ASP.NET or Windows Forms. In HTML and ASP.NET it's quite obvious. In Windows Forms, one would simply use a selection to point out the text to change the font for that text, including the color.

In Silverlight 2, this is done trough the use of a TextBlock and it's Inline property. The Inline property is of the type InlineCollection, which is, offcourse, a collection of Inline objects. The Inline class in turn, is an abstract class that is inherited by two other classes, being Run and LineBreak. You would use Run to define a run of text and you would use LineBreak for it's obvious purpose of going to the next line.

I used this in XAML to define the tooltip you can see in the screenshot. It looks like this:

<TextBlock x:Name="matchesTextBlock">
<ToolTipService.ToolTip>
<ToolTip>
<TextBlock>
<Run>Matched text is colored red,</Run>
<LineBreak />
<Run>while unmatched text is colored black.</Run>
<LineBreak />
<Run>If the expression matches the entire</Run>
<LineBreak />
<Run>input, the background will color gray,</Run>
<LineBreak />
<Run>otherwise it will color white.</Run>
</TextBlock>
</ToolTip>
</ToolTipService.ToolTip>
</TextBlock>


As you see, once you get used to it, it isn't that hard. As you can aply a seperate style to each Inline element you can easily write some code to highlight the matches from a regular expression. The method that does it looks like this:


private void UpdateMathes()
{
string input = inputTextBox.Text;
string expression = expressionTextBox.Text;

MatchCollection matches = Regex.Matches(input, expression);

bool isMatch = matches.Count >= 1 && matches[0].Length == input.Length;

matchesTextBlock.Inlines.Clear();
int writtenChars = 0;
foreach (Match match in matches)
{
string inputToMatch = input.Substring(writtenChars, match.Index - writtenChars);
DrawUnmatchedText(inputToMatch);
writtenChars = match.Index + match.Length;
string matched = match.Value;
DrawMatchedText(matched);
}
string inputAfterMatch = input.Substring(writtenChars, input.Length - writtenChars);
DrawUnmatchedText(inputAfterMatch);

if (isMatch)
{
matchesBorder.Background = new SolidColorBrush(Colors.Gray);
}
else
{
matchesBorder.Background = new SolidColorBrush(Colors.White);
}
}

Some of you may have spotted the way that isMatched is filled and think that using Regex.IsMatch would be a more efficient way of doing this. Unfortunately Regex.IsMatch returns true if any match is found, so even a partial match would return true.

The two methods that do the actual work look like this:

private void DrawUnmatchedText(string text)
{
Run run = new Run();
run.Text = text;
run.Foreground = new SolidColorBrush(Colors.Black);
matchesTextBlock.Inlines.Add(run);
}

private void DrawMatchedText(string text)
{
Run run = new Run();
run.Text = text;
run.Foreground = new SolidColorBrush(Colors.Red);
matchesTextBlock.Inlines.Add(run);
}


So this is how you can easily format your text inside a textblock. As you may already know, I'm always keen to get your feedback on any of my articles and I'm always happy to answer any questions, so please leave your comments below.

UPDATE 31-03-2010: You can now download the original Silverlight 2 source from here. Thanks go out to alexander pointing out he was missing some source.

Monday, December 1, 2008

Silverlight 2 Datagrids RowDetailsTemplate and databinding radiobuttons

Today something I've been testing with for future use. I've been building a small prove of concept for using the datagrid to edit data, not directly in the grid, but in a details form. It looks like this:


So you can click a row and the details form is displayed below the row. You can then edit the data and it is immediately shown in the grid.

In this article I'll assume you have some knowledge on databinding and the datagrid yourself. Also having some experience with Silverlight, XAML, Blend and Visual Studio would come in handy.

So how does this work? This uses the RowDetailsTemplate property of the datagrid.

The RowDetailsTemplate in Blend
I started building this in Blend and ended up in Visual Studio anyway. Blend does provide support for editing this template, trough the menu Object &lt; Edit Other Templates &lt; Edit RowDetailsTemplate. You can build up a template here, but it's visual designer is not really user friendly.

Then comes the databinding. The datagrid is easy. Just go to the Project panel and under data add a CLR object, in this case a collection and drag it onto the grid. You can then turn off AutoGenerateColumns and define your own columns trough the Columns collection.

For the RowDetailsTemplate this doesn't work that polished. You can go to a control, let's say a textbox, and databind to it's properties, in this case the text property. A nice Create Data Binding dialog comes up and I taught "ok, just bind to the collection and we're done". But clicking on the collections datasource created earlier only shows the count property. So I figured I'd add a datasource for the detailed class and bind to the property there. The dialog allows you to do this, but as soon as you close it errors start popping up telling you that a TextBox can't be converted into a DependencyObject (don't ask me why not) and the datasource you just created can't be resolved.

Checking the XAML shows that Blend did exactly what I asked, binding to the datasource I created, with the path I clicked on. But this is not what I want. I just want to bind to the actual datacontext, so at this point I fired up Visual Studio to edit this mess myself (as Blend doesn't support any IntelliSense, I prefer Visual Studio as a XAML editor). I simply changed the binding to {Binding propertyname} and it works like a charm.

So next up, I wanted to databind two RadioButtons to one field.

Databinding radiobuttons
In the process of building a small form to show how this could work in future applications, I wanted to bind a field (in this case a persons Gender field) to two radiobuttons (obviously Male and Female). I googled around a bit and found out that this is not as straight forward as one might think. Some people actually wrote a considerable amount of code to get it to work.
I pondered on this a bit and decided that I would come up with an approach using ValueConverters. You can build custom ValueConverters simply by creating a class that implements the IValueConverter interface. From there on it's actually not that hard.

I came up with using two value converters, one for the male and one for the female. Here is what the Female one looks like:

public class GenderFemaleConverter : IValueConverter
{
#region IValueConverter Members

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool result = false;
Gender actualValue = (Gender)value;
result = actualValue == Gender.Female;
return result;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool actualValue = (bool)value;
if (actualValue)
{
return Gender.Female;
}
else
{
return null;
}
}

#endregion
}


For the male version of this, all I changed where the Gender.Female references to Gender.Male. Then all you have to do is use these in your databinding. To do so, first you'll need to create resources for them at some point. In this case I put the resources in the UserControl. The XAML looks like this:

&lt;UserControl.Resources>
&lt;DataClasses:PersoonCollection x:Key="PersonCollectionDS" d:IsDataSource="True"/>
&lt;local:GenderFemaleConverter x:Key="GenderFemaleConverter" />
&lt;local:GenderMaleConverter x:Key="GenderMaleConverter" />


Next step is to include these resources as converters in your databinding:


&lt;RadioButton Grid.Row="1" Grid.Column="3" Content="Male" IsChecked="{Binding Gender, Converter={StaticResource GenderMaleConverter}}">&lt;/RadioButton>
&lt;RadioButton Grid.Row="1" Grid.Column="4" Content="Female" IsChecked="{Binding Gender, Converter={StaticResource GenderFemaleConverter}}">&lt;/RadioButton>


As you can see, I bind both RadioButtons to the same field, but I use the two different converters.
One could argue that this is not the most efficient way of doing things and I would agree. A better approach may be to build some sort of RadioGroup control that has a single converter and databinding happens to a property of that. For this prove of concept however, it does what is has to do.

I hope you enjoyed this article and found it helpful. Please let me know if there are any questions and also suggestions for subjects are still very welcome, although I might not be able to go into every single thing you throw at me.

Wednesday, November 26, 2008

Building maintainable code with Visual Studio 2008 Code Metrics

Today I decided to do some refactoring on my code, with the main purpose of improving maintainability. As most of you probably know Visual Studio provides some nice tools to indicate which code could use the most improvement. Since Visual Studio 2005, several editions contain Code Metrics. As you run code metrics however, it can be hard to determine how to improve the indicated parts of the code, so that it's Maintainability Index (MI) goes up. In this article I'll try to give some insight into what makes up the MI and how this effects your code.

Let me start by saying that this is in no means a complete and/or exact explanation. The main purpose of this article is to give the insights needed to improve MI numbers on your code.
Second, Microsoft seems to think that an MI of 20 or more is enough. I don't agree and advice any professional development team to set a value that is way higher than this. I've never even written a method that scored lower then 50 and these methods are still not the most clear methods (using recursion, not placing any comments and involving LINQ in a 50 line method).

Also, don't get caught up on this one method in a hundred that you can't seem to improve. If you have a good reason to write a method that still doesn't meet your minimal MI requirement, place some comment stating the reason and leave it alone.

The main components
The MI is made op of several other metrics:
- The Halstead Volumne (HV)
- The Cyclomatic Complexity (CC)
- The number of lines of code in the module (LOC)

Some universities (the Vrije Universiteit in Amsterdam and the Carnagie Mellon University, at least) argue that the percentage of comments in the module should also be included in the calculation of the MI. Unfortunately FxCop calculates the MI based on the IL code, so comments are not taken into account.

So what counts the most in calculating the MI? Well in FxCop, the LOC is actually the most important, reasoning that the less lines of code you have, the easier it is to maintain that code. I would agree to this. The second most important value is the HV, which I will explain in some more detail later.

And to what rate are the LOC and HV more important to the CC in FxCop?
The LOC actually makes up for about 75% of the MI, the HV accounts for about 24% and the CC accounts for the final 1%.
(You can find the actual calculation here)

A close look at the Halstead Volume
As this makes up about 24% of the MI metric, let's have a closer look. I won't bother you with the complete details, as this article is already long enough.

Basicly the HV is based on the assumption that all code is made up of operands and operators.
The calculation involves both the total number of operands and operators and also the distinct number of operands and operators.

Operands are identifiers, types and constants and operators are basicly all the other peaces of code (except comments, of course).

Conclusion
So how do you improve your MI metric? The first priority is to have less lines of code. The second priority is to reduce the amount of different operators and operands in a particular module. Both of these actions usually result in splitting up methods.

Again I would like to state that the MI metric is far from perfect and it should not be a definitive guide to what to refactor. It's only an indication of what to look at and I really think that it would be valuable to have comments taken into account, as well as have a slightly higher role for CC in there.

Please let me know your experiences on this subject trough the comments option below.

Friday, November 21, 2008

Exception causes Xml Error in deserialization

This week I seem to run into quite a few nooks and crannies in the .NET framework that put me in front of some tricky issues. This time it had to do with deserialization, or so Visual Studio led me to believe.

Here is the situation. Last week I wrote some code that deserialized an xml file into an elaborate object model. Part of that code was to parse an xsd file and add some objects to the model from there. This all worked well for the past week, as proven by the unittests.

Yesterday I started writing some code to dynamicly load assemblies and classes based on some information from the xsd file. I didn't get to finish it, but as I started working on it this morning, all of a sudden it threw an exception on the deserialization code, stating that I had some error in my xml file. I checked my xml file, which I knew I hadn't changed, and off course it was fine.

So I figured that since the last change I made was in some code that parsed part of the xsd file, I would debug there. As it appeared, the exception occurred whenever I passed a certain XPathNavigator instance into a method of my Factory class for creating a plugin. My first tought was that this occurred because I passed the XPathNavigator to another method. I started to program around this approach, but to no avail.

I crunched my head on it for another half hour until I had to leave for a meeting, but as I came back and looked at my code I realized I actually called the initializer method of a Factory class that I use to load some pluggable classes. I started debugging this method and presto, it raised an exception, because of some small oversight. I fixed this exception and the deserializer code worked again.

Conclusion on this is that some code in the XmlSerializer or it's base classes, catches any exception thrown and re throws another exception which is not related to the actual problem. Fortunately, the inner exception does contain the actual exception, meaning I could have saved myself a lot of time and headaches, by simple looking an the inner exception.

Another thing I learned was that using a singleton pattern to create your factory class is a good thing, but you must pay some attention when debugging.

Thursday, November 20, 2008

Plugins and abstract static methods in C#

Here is what I ran into today. I'm currently working on this service that has to be expendable in some parts of the code. Because of the way things have to work, I figured I would use a technique based on plugins. I will look in a particular folder and load any assemblies available there. Then I will get all the types that derive from a certain base class and select the write plugin class based on some statically available information and then create an instance of this class...

...and that's where it all goes boom. Here is what I wanted to write as a base class:


public abstract class PluginBase
{
public abstract static string[] SupportedOperations { get; }

public abstract void ExecuteOperation(string operation);
}


I would then just loop trough the found plugin class types and check inside SupportedOperations to find out which plugin would be able to handle the task at hand. That won't work, because C# has no support for an abstract static member (so changing it into a method won't work either).

The reason for this, as I've read from several compiler designers at Microsoft, is that the compiler considers static members in derived classes as completely unrelated and it would be hard to resolve to the correct member and not very transparent to developers.

This also crushed any hopes of solving this with an interface, as an interface is implicitly abstract.

You can read a lot on the subject on these links:
http://msmvps.com/blogs/jon_skeet/archive/2008/08/29/lessons-learned-from-protocol-buffers-part-4-static-interfaces.aspx
http://blogs.msdn.com/ericlippert/archive/2007/06/21/calling-static-methods-on-type-variables-is-illegal-part-three.aspx
http://bytes.com/forum/thread238034.html
http://weblogs.asp.net/justin_rogers/articles/61042.aspx

I guess this means I'm not the only one that would like to use this as a feature (let me know, trough the comments).

If you read the comments on the first link, you may also run into this article, that actually shows that abstract static members are possible in IL. It's just not supported in C# (or any other well known .NET language for that matter).

So basically what is it that I want? I want a way to specify that any class derived from some base class has a specific static member that I can call. This can't be done, so I now know.

How did I solve it? I really didn't, but I went and made some design decisions. First of all I will add the static member to the base class, but not make it abstract, so my base class has an implementation of it's own. The base class implementation will return an empty string[], so I know it doesn't support anything (it's the abstract base class, what did you expect?).

Then how do you handle derived classes that don't have their own implementation of the static member? This depends on the use of the plugins. In my case, they are used in a service that has to be able to run unattended. For this reason I decided to apply defensive programming and simply ignore classes that don't implement the static member themselves.
In other cases it may make perfect sense to throw an expection, or handle it differently.

I hope this makes sense. If you have questions just let me know.

Wednesday, November 19, 2008

Using Source Control with Silverlight 2 and non-standard fonts

I just ran into this and tought I'd post a heads-up. When you build a Silverlight Class Library and use some fonts in it, that are not standard to Silverlight 2, the fonts you use are delivered to the browser plugin. To make it all work, it uses SubsetFontTask.dll. To make the fonts available it uses a .targets file which is imported into your project trough an tag.

This is all very nice and works as one might expect. Also its nice and transparent. If you don't look for it you probably don't even notice...

...until, that is, you add your project to source control. It appears that everything is just fine, until a collegue tries to get the same project working on his or her own computer. Then Visual Studio throws a nasty error about not being able to import the .targets file.

Fortunatly it's easy to fix. Just add the .targets file to source control. And then you simply do get latest version and...

...it breaks again, because it can't find the SubsetFontTask.dll in the root of the project where it expects it. So we add this file to source control as well. And then finally it works.

This doesn't seem right. I would expect that whenever I add a project to source control trough Visual Studio, it checks in all the files that are needed to build a project on any machine, that is properly installed.

Please let me know what you think about this, trough the comments below.

Friday, November 14, 2008

Unittesting and code coverage

Recently it was decided that all newly constructed code that our company builds, has to be unittested. Although this may seem like a late call, for a lot of product companies this is quite a big step and I, in contrast with a lot of developers out there, was happy to hear this...

...Until, that is, some mentioned that we should reach 100% code coverage. Now I know some of you out there would say that this should be the case, but I think differently. Let me explain.

Let's say you have some method that has to find an object in some hierarchy. At some point you end up writing some code like this:

FindableObject FindObject(string name)
{
FinadbleObject result = null;

foreach (FinadbleObject subObject in _subObjects)
{
if (subObject.Name == name)
{
result = subObject;
break;
}
else
{
result = subObject.FindObject(name);
if (result != null)
{
break;
}
}
}

return result;
}

It would work like a charm. Let's say you now write a unittest for this method. You set up a hierarchy of three objects and try to find the deepest one by calling FindObject on the top one. The result of the unittest would be a pass if the result of the method equals the initial object you placed there. Problem is, you would not reach 100% code coverage of your method, because the last } that belongs to the foreach loop would not be reached.

The only way to do this, is to write a unittest that will not render a result as it calles FindObject. Although this may very well be a valid unittest, I'd say that writing several lines of code, simply to test a closing curly bracket is somewhat over the top.

Another reason why I think having 100% code coverage in unittesting is highly impractical, is that you would have to test stuff like getters and setters on properties, even if they don't contain any code.

Please let me know if you think otherwise and have some compelling reason to still reach 100% code coverage, by dropping me a comment. I'm still open for debate on this.

Wednesday, November 12, 2008

Adding a customdictionary.xml to your project for use with FxCop

Today I was cleaning up some code I wrote, so I decided to run FxCop on my project to help me identify possible issues. The first warning I ran into was a "misspelled" word. In fact it was a term from our Business Layer which was in dutch, so I wanted FxCop to ignore it.

Reading the help topic on this warning pointed me in the direction of the CustomDictionary.xml file, which allows you to influence the way spelling is checked by FxCop. The help topic states that you can define one on installation level for the tool, on user level or for the project. In this case I decided it would be part of the project so I would work for the rest of our team as well.

So I simply added a CustomDictionary.xml to my project, looking like this:


<?xml version="1.0" encoding="utf-8" ?>
<Dictionary>
<Words>
<Recognized>
<Word>Translatie</Word>
</Recognized>
</Words>
</Dictionary>


Obviously MyWord replaces the actual word I needed to add, but you get the picture. So I ran FxCop again and my "misspelled" word still raised a warning!!

Googling on this subject got me to Duncan's Blog, who wrote this post about it. Simply changing the Build Action on the CustomDictionary.xml file (in the properties) to CodeAnalysisDictionary did the trick.


By the way, please tell me what you think about my blog, by posting a comment. Thanks.

Using XmlSerializer to serialize type information

During the development of a project I'm currently working on, I ran into this. One property of a class I defined is called SimpleType and it holds a Type object. It contains some basic type like int or string.
Part of the project is to store this information and have it easily configurable, so my first thought was to use the XmlSerializer class to simply serialize the objects inside a collection to an xml file. So I wrote some code to do this:


XmlWriter writer = XmlWriter.Create(@"c:\temp\template.xml");
XmlSerializer serializer = new XmlSerializer(typeof(Template));
serializer.Serialize(writer, template);
writer.Close();


Running this code threw a nice exception: "The type System.Int32 cannot be used in this context". At first I was stunned. I didn't have any properties that even related to int. Then I figured it must be the SimpleType property and I needed some kind of workaround for this behaviour.
Here is the code of the property I tried to serialize:


public Type SimpleType { get; set; }


To make it work I started by adding an XmlIgnore attribute to the SimpleType property. This obviously prevents the serializer from including it into the xml file and stops the error from occurring, but now I had no type information in my xml file and I did need it.
So I added a private field to store the type in and added a second property called SimpleTypeName of type string.
The getter of this property simply returns the SimpleTypes Name property. The setter uses the static Type.GetType method to translate a typename into a Type object and sets it in the field.
Here is the code after I rewrote it:


private Type _simpleType;

[XmlIgnore()]
public Type SimpleType
{
get
{
return _simpleType;
}
set
{
_simpleType = value;
}
}

public string SimpleTypeName
{
get
{
if (_simpleType != null)
{
return _simpleType.Name;
}
else
{
return string.Empty;
}
}
set
{
_simpleType = Type.GetType(value);
}
}


To make this work you obviously need the namespace System.Xml.Serialization.

If you have any questions or remarks, please feel free to comment below.

Sunday, November 9, 2008

Using the popup element in Silverlight

It's been a while, as I was realy busy with getting our latest project of the ground, but finally here we are again.

This time, I wanted to look into the use of the popup element, as I plan on using this in future applications to handle some basic use cases. One of those is displaying a message to the user, for example an error message.

I started out with a simple application containing a grid as this is what most of my applications look like. As I wanted my popup to center in the browser window I added a canvas to the top left cell of the grid (in my case that would be the top row). Then I spanned the canvas trough all the rows and columns, so I covers the entire window. My xaml looks like this:


<grid name="LayoutRoot" background="White">
<grid.rowdefinitions>
<rowdefinition height="100">
<rowdefinition height="*">
<rowdefinition height="100">
</Grid.RowDefinitions>
<textblock row="0" margin="10" fontsize="20">Errorbox demo</textblock>
<button row="1" content="Throw error!" margin="20" click="Button_Click">
<textblock row="2" margin="10" verticalalignment="Bottom">Click the button to see a Popup control in action</textblock>
<canvas name="rootCanvas" row="0" rowspan="3">
</canvas>
</grid>


Next step is to actually build the popup for displaying error messages. It's as simple as wrapping any xaml you want for your popup inside a popup element. If you use Blend, like I do, what you may notice is that it doesn't display the popup by default. To have it displayed, you have to select the popup in the Objects and Timeline window. It then shows you the popup and it's contents.

The xaml for the popup looks like this:


<Popup x:Name="errorPopup">
<Border Background="#FFFFFFFF" BorderBrush="#FF000000" Height="300" Width="400">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="15" />
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Border Grid.Row="0" CornerRadius="15,15,0,0">
<TextBlock x:Name="TitleTextBlock"></TextBlock>
</Border>
<TextBlock Grid.Row="1" x:Name="ErrorText"></TextBlock>
<Border Grid.Row="2" CornerRadius="0,0,15,15">
<Button x:Name="OkButton" Width="100" HorizontalAlignment="Right" Margin="5" Content="Ok" Click="OkButton_Click"></Button>
</Border>
</Grid>
</Border>
</Popup>

So now we can write some code to popup our message. One thing that got me googling was how to actually show the popup. You use the IsOpen property which is a boolean. My code for displaying the popup looks like this:


public static void PopupError(Exception error, Canvas parent)
{
ErrorBox errorBox = new ErrorBox();
errorBox.Error = error;
parent.Children.Add(errorBox);
Canvas.SetLeft(errorBox, (parent.ActualWidth / 2) - errorBox.Width / 2);
Canvas.SetTop(errorBox, (parent.ActualHeight / 2) - errorBox.Height / 2);

errorBox.errorPopup.IsOpen = true;
}


When you want your popup to close, simply set the IsOpen property to false again. Note the use of the ActualHeight and ActualWidth. These are important because these are the dimensions that where set after rendering instead of the Height and Width property that are set in design mode. Another thing that you may run into is that these are set to 0. in the Loaded event of the page AND also in the Loaded event of the Canvas. If you rely on these events some redesinging is required to get this to work.

You can now download the project here. It's not all polished up, but you'll get the picture.

By the way, please let me now what you think about my blog and if there are any topics you would like to read about.

Friday, October 31, 2008

The Visual Studio Start Page

Have you ever wondered why on earth there is a start page in Visual Studio? I know I have. Usually I only click a recent solution here, but today my eye stuck on some info in the news presented here. You can now get a free copy of CodeRush and Refactor! Pro (with limited features of course).

You can find more info here, where Charlie Calvert writes about it, and you can download it here.

So now we all have a good reason to stroll trough the news on the Visual Studio start page every now and then.

Thursday, October 30, 2008

Lookup Combobox in Silverlight 2

I ran into this problem while building a proof of concept to introduce SilverLight 2. I needed a datagrid, with several columns where the values of these columns are determined by a single combobox. Putting the combobox in place was easy enough, but getting the other columns to react instantly got me googling for quite a bit (altough in the end the solution is obvious).

As an example for this post, we will use a car database (cause I love cars). A car has a brand, a type and an engine. An engine consists of a type, a fuel and a number of cillinders. I've placed a datagrid in my page.xaml and configured it a bit. It then looks like this:


The Engine column contains a combobox that appears whenever you edit a row. The Fuel and Cillinders columns are actually databound against the engine class, like this:


<?xml:namespace prefix = data /><data:datagridtemplatecolumn header="Engine">
<data:datagridtemplatecolumn.celltemplate>
<datatemplate>
<textblock margin="4" text="{Binding Engine.TypeCode}">
</datatemplate>
</data:datagridtemplatecolumn.celltemplate>
<data:datagridtemplatecolumn.celleditingtemplate>
<datatemplate>
<?xml:namespace prefix = cardemo /><cardemo:fixedcombobox selecteditem="{Binding Engine, Mode=TwoWay}" itemssource="{StaticResource Engines}">
<combobox.itemtemplate>
<datatemplate>
<stackpanel orientation="Horizontal">
<textblock width="40" margin="4" text="{Binding TypeCode}">
<textblock width="40" margin="4" text="{Binding Fuel}">
<textblock width="20" margin="4" text="{Binding NumberOfCillinders}">
</stackpanel>
</datatemplate>
</combobox.itemtemplate>
</cardemo:fixedcombobox>
</datatemplate>
</data:datagridtemplatecolumn.celleditingtemplate>
</data:datagridtemplatecolumn>
<data:datagridtextcolumn header="Fuel" isreadonly="True" binding="{Binding Engine.Fuel}">
<data:datagridtextcolumn header="Cillinders" isreadonly="True" binding="{Binding Engine.NumberOfCillinders}">
</data:datagridtextcolumn></data:datagridtextcolumn>
<data:datagridtextcolumn header="Fuel" isreadonly="True" binding="{Binding Engine.Fuel}"><data:datagridtextcolumn header="Cillinders" isreadonly="True" binding="{Binding Engine.NumberOfCillinders}"></data:datagridtextcolumn></data:datagridtextcolumn>

But like this it won't update the read-only columns for fuel and cillinders whenever I choose a different engine. To do this, we need to implement the INotifyPropertyChanged interface on the car class (in fact I would advise implementing it on all your databound classes):

public class Car : INotifyPropertyChanged
{
private Engine _engine;
private string _brand;
private string _type;

public Engine Engine
{
get
{
return _engine;
}
set
{
_engine = value;
RaisePropertyChanged("Engine");
}
}

public string Brand
{
get
{
return _brand;
}
set
{
_brand = value;
RaisePropertyChanged("Brand");
}
}

public string Type
{
get
{
return _type;
}
set
{
_type = value;
RaisePropertyChanged("Type");
}
}
#region INotifyPropertyChanged Members

private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

public event PropertyChangedEventHandler PropertyChanged;

#endregion

Now, the datagrid will subscribe to the PropertyChanged Event of your class as it binds to it. Then, whenever you choose a different item in the combobox, this changes the engine property and triggers the event. This in turn triggers the datagrid in updating the other columns.

Update: As of the December '08 release of the datagrid, a fix on the combobox is no longer needed.

Wednesday, October 15, 2008

Getting to know your software

I've spend the last two days on a course for basic use of the software I'm going to improve. Seems like a waste of time? Read on.

Getting to know your software as a user
Developers of software are used to looking at software as a developer. There are very few times a developer looks at software as a user. What is the difference, I here you ask?

A user looks at software and sees what work is needed to reach his or her goals. The user values software based on how much work is needed to reach the goal and how much of it is tedious in the software.

A developer looks at software and thinks about the technology behind it and how much work it was to do this particular feature that he or she thinks is so great.

The fact of the matter is that a lot of the times, developers spend a lot of time building features that the user doesn't use very often. This sounds like it's frustrating for the developer, but he or she will hardly ever know this (thinking the lack of support calls is a testament to the greatness of the code and not to the lack of usage :-) ).

To improve this, playing around with your own software in a course can be very helpful. It's usually more productive than doing this at your usual desk, because of the distractions that are around. Also, a good trainer encourages you to work with the software and provide some practice examples.

Improving user awareness
The traditional way of improving on this would be to interview key users, but this is very unusual in a product development setting. Requirements and functional specifications are written by a department inside the company and developers just need to build according to these specifications.

So another way to get to know your users is to go to a user course of your own software.
This not only puts you in contact with some users, but it can also point out weaknesses in the functionality (or even technical issues, but then something is wrong in the testing process). A user course can do that trough the training material. Another thing to look for is explanations of the instructor. Ask yourself "why does this need explaining?".

And last but not least, questions of the users themselves are a valuable input. It may very well be that you would consider a screen perfectly intuitive, but your user may not understand it at all.

Conclusion
A basic user course a waist of time? I'd say no and encourage all developers to give this a try.

Monday, October 13, 2008

Resizing images

It was one of those days again. You build someone a .NET library to convert WMF images inside an OLE package to a clean JPEG file from MS Access and the first thing they say is, "Can it resize the image?". I'll spare you the why and skip right to the how :-).

Requirements
First thing to think about is how you want this resizing to behave. You could resize just for size, but in our case we wanted to save space. Also we wanted to keep the aspect ratio and we only wanted to shrink images, not make them larger.

Keeping aspect ratio meens that only one of the dimensions can be specified. In our case this was always going to be the height, which would be specified in millimeters.

The process
It takes the following steps to resize an image based on a new height:
  1. Calculate the vertical resolution of the image in pixels/mm
  2. Calculate the new height
  3. Calculate the factor by which the image is being sized
  4. Calculate the horizontal resluotion in pixels/mm
  5. Calculate the new width based on the old one, the horizontal resolution and the sizing factor

The code
So let's dive into the code. First thing we need is a field and a constant to store some values in:

private const double mmPerInch = 25.4;
private double _sizingFactor;


The first step is to calculate the vertical resolution of the image in pixels/mm:

double pixelsPerMm = image.VerticalResolution / mmPerInch;


Then we can calculate the new height, taking into account that we don't want to change heights that are smaller then the preferred height:

if (image.Height / pixelsPerMm <= height)
{
_sizingFactor = 1;
return image.Height;
}
double newHeight = pixelsPerMm * height;


After this we can calculate the factor by which the image is being sized:

_sizingFactor = height / (image.Height / pixelsPerMm);


Then we calculate the horizontal resluotion in pixels/mm:

if (_sizingFactor == 1)
{
return image.Width;
}
double pixelsPerMm = image.HorizontalResolution / mmPerInch;


And we calculate the new width based on the old one, the horizontal resolution and the sizing factor:

double newWidthMm = (image.Width / pixelsPerMm) * _sizingFactor;
double newWidth = newWidthMm * pixelsPerMm;


Finally, resizing the image is easy. I've wrapped the code in some methods and constructed a Size construct:

int newHeight = CalculateHeight(image, height);
int newWidth = CalculateAspectRatioWidth(image);
return new Size(newWidth, newHeight);


Then we can resize an image like this:

Bitmap outputBitmap = new Bitmap(bitmap, CalculateNewSizeByHeight(bitmap, height));

Thursday, October 9, 2008

MS Reporting Services 2005 non-standard layout tip

One of my collegues asked me to find a way to display data in a SSRS 05 report in three columns, much like an address cards page. The obvious way would be to just have three datasets, but this is not an ideal approach.

I've been checking out some different possibilities and came up with more then one solution (which is always a good thing, right?)
A common factor in all this is that you need row numbers. Alltough SSRS supplies rownumbers trough the RowNumber() function, you can not use this function in either grouping or filtering, so I needed an alternative.
Looking into getting the rownumber from the database, I decided to have a go with the Row_Number() statement in T-SQL. This proved to be a winner.

I've created two solutions by using the row number. One approach is to assign each row a number according to the column that the row should be displayed in, simply by deviding the row_number by three and using the remainder as my group number.
Then I used three lists that filter the data on the group number. Inside the list I use a rectangle as a container for the data, so each row takes the same physical space in the report.

Another way of doing things is using a matrix and calculation two numbers, one group number, like with the lists approach, and one number that is calculated by adding 0.5 (this is needed for rounding purposed) dividing by three and rounding the result. This results in each set of three records having a number (so record 1 trough 3 have number 1 and records 4 trough 6 have number 2, etc.). Now you can use the first field as a groupfield for the columns and the second field as a groupfield for the rows.

Another way that might work (haven't tested this one) is to use a table.