BLOG - Filter: .NET
WPF Grid: Percentaged columns height/width
Samstag, 18. Juli 2009, Christoph Ertl

WPF 3.5 SP1When defining rows of a WPF grid you can use several ways to set the height of the row. Automatic, absolute values or relative values. But there's no notation for percent values.

But instead of writing Height="25%" you just use the relative notation.

<Grid.RowDefinitions>
 
<RowDefinition Height="25*" />
 
<RowDefinition Height="75*" />
</
Grid.RowDefinitions>

 

Using this notation with databinding

Assume we have a simple data class

public class Data {
 
public int Percent1 { get; set; }
 
public int Percent2 { get; set; }
}

and bind the two properties to the two rows of the grid

<Grid.RowDefinitions>
 
<RowDefinition Height="{Binding Path=Percent1}" />
 
<RowDefinition Height="{Binding Path=Percent2}" />
</Grid.RowDefinitions>

and assign the DataContext property

DataContext = new Data() { Percent1=25, Percent2=75 };

we get a grid with the first row's height set to 25 and second row's height set to 75 in absolute values. As you can see the rows have the correct height but they do not use the whole height of the grid. To get this fixed we need to use the star notation again.

We need to convert the values to get the visual result we want. And the conversion must be done at the data binding because it's part of the presentation of the data and not the data itself.
When working with WPF (not only in WPF) you should always consider if the logic is part of the presentation or the data being presented.

Converting the bound values

To convert the values we create a simple converter class implementing the IValueConverter interface placed in the namespace System.Windows.Data. We just need to implement the convert method adding the star at the end of the value.

class PercentConverter : IValueConverter {
 
public object Convert(object value,
                       
Type targetType,
                        object parameter, 
                        CultureInfo culture) {
   
return value.ToString() + "*";
  }

  public object ConvertBack(....)
}

When we now use the converter for databinding

<Grid.RowDefinitions>
 
<RowDefinition Height="{Binding Path=Percent1,Converter={StaticResource PercentConverter}}" />
 
<RowDefinition Height="{Binding Path=Percent2,Converter={StaticResource PercentConverter}}" />
</Grid.RowDefinitions>

we get the result we wanted to have.

Different behavior in Debug and Release version of a .NET application - How to find the bug
Samstag, 06. Dezember 2008, Christoph Ertl

binary conflict A few days ago I had a problem at a .NET 1.1 project where the release version of the application had a different behavior than the debug version. I felt like in the old days when developing with C++ and struggling through precompiler instructions.

The beginning

Tried to reproduce the bug with a Unit test which was not possible. Had a detailed look at the production data and refined the unit test. No success. At this point I had the suspicion that this could' be a debug vs. release problem. Tried the unit test in release mode and the test failed.

OK. There's a difference but how to find out where and what is the difference? And if found, why is there a difference?

Where's the difference?

Even with the information from the unit test it's not easy to find out why there is a difference. First of all we have to find the location of the difference. To find the location I used a profiler while running the unit test in debug and in release mode.

Then I compared the two call stacks and within seconds I got the method where the difference was located.

image 
callstack (orderd by execution time) as expected in the debug execution.

 

image
different callstack (ordered by execution time) in the release execution.

What's the difference?

Now we know the method were the difference is located. The next step is to compare the code of the release and debug assembly. This is best done using Redgate's .NET reflector.

Comparing the methods is an easy task with .NET Reflector. If your method is too large you can use an add-in which supports comparing two assemblies.

Why is there a difference?

While comparing the two version of the code you see in detail what's different. But why?

The difference can be caused by some reasons:

  1. Removed code in release assembly because of the Conditional attribute.
    Check the method which is missing in the callstack if it is marked with this attribute.
  2. The difference can also be caused by a compiler optimization like inlining etc. but this should not lead to a different behavior unless there is an
  3. Error in the compiler
    In this case you must try to change your code and see what's the result. A detailed inspection and understanding of the differences can help.

The found bug

For the sake of completeness the details about the bug I found. This bug only arises with the compiler shipped with Visual Studio .NET 2003. With Visual Studio .NET 2005/2008 there were no problems.

The code written in the editor:

private static void DoIt(bool flag) {
 
if(flag) {
   
using(MyDisposable d = DoItNormal()) {
   
}
 
}
 
else {
   
DoItDifferent();
 
}
}

The debug version inspected with .NET Reflector:

Debug assembly inspected

The release version inspected with .NET Reflector:

Release assembly inspected

Removing the empty using block and calling Dispose() explicitly solves the problem.

References

Url Rewriting in Umbraco - Friendly Tag Filter
Samstag, 15. November 2008, Christoph Ertl

After finishing the Tag Cloud package the next step to improve my web site was to get rid of the ugly query URLs when filtering blog posts by tag.

The Goal

Instead of

/blog.aspx?filterBy=TagName

I wanted something like

/blog/tag/TagName

Why ?

  1. As we all - techies of course - know search engines are not happy with URLs like this
  2. I also had the impression that Google AdSense didn't distinguish the pages correctly.
  3. I personally don't like URLs containing query parameters on a web page as they are not user friendly.
  4. Some kind of perfectionism

The Solution

It's that simple that I was not sure if it's being worth posting. But it took me a while to find the solution. Like in most cases. It's easy if you know where and how to do it. It would be easier if the feature would be mentioned in the feature list or online help. However, here it is:

In the file /config/UrlRewriting.config one can place rules for rewriting URLs. Just add a rule like this.

<add name="tagfilter"
  virtualUrl="^~/blog/tag/(.*).aspx"

 
rewriteUrlParameter="ExcludeFromClientQueryString"
  destinationUrl="~/blog.aspx?filterBy=$1"

 
ignoreCase="true"

/>

A detailed description how it works can be found in the file itself.

One important thing is that without reconfiguring the IIS Server the URL must end up with .aspx. So the new URL looks like this

/blog/tag/TagName.aspx

which is very straight forward as all other nodes are also referenced using the aspx extension.

References

  • This Umbraco feature is powered by the ASP.NET UrlRewritingNet component which can be found at http://www.urlrewriting.net/
  • A Post where the feature is at least mentioned.
  • A Post from Warren where he points to some problems using this feature.

CMS - Die Qual der Wahl
Sonntag, 06. April 2008, Christoph Ertl

Dass man heutzutage eine private Homepage hat ist ja nicht mehr ungewöhnlich. Was mich aber besonders freut ist, dass mein Vater mit über 70 Jahren auch eine Homepage möchte.
Immerhin hat er einige Jahrzehnte als Maler sein Privatleben bestritten und die Kunstwerke wollen ja auch präsentiert werden. Neben den Ausstellungen, die er immer wieder macht, ist natürlich das Internet ideal. Und mit dem Computer und somit auch dem Internet beschäftigt er sich ja ohnehin.
Nach einigen Abenden mit Diskussionen und Anregungen ist seine Seite jetzt online.
Also wer an Kunst und im speziellen an Malerei interessiert ist, hier geht's zur Seite www.hansjoerg-ertl.net

Die Auswahl des CMS

Um die Seite zu realisieren und weiterhin auch pflegen zu können sollte natürlich ein CMS her. Aber welches? Folgende Anforderungen standen bei der Wahl im Vordergrund:
  1. Klare Trennung von Inhalt und Präsentation
  2. Einfache Handhabung für denjenigen der den Inhalt pflegt
  3. Einfache Korrektur der Struktur und Präsentation über das Internet (verteiltes Arbeiten)
  4. kostenlos

Punkt 1 sollte implizit klar sein wenn man von einem CMS spricht, darum habe ich mich also vorerst gar nicht gekümmert. Aufgrund Punkt 2 war die Idee eines Clientseitigen CMS naheliegend auch wenn das Punkt 3 eigentlich ausschließt. Aber strukturelle Änderungen sind ja nur im Vorfeld zu erwarten und bei einer privaten Seite keine Sache die sofort erledigt werden muss.

Clientseitiges CMS

Ein clientseitiges CMS kann von der Usability her am besten mit der von anderen Programmen gewohnten Oberfläche und der damit verbundenen Interaktion aufwarten.

Nachdem ich mir etliche dieser Programme angesehen habe, bin ich zu der Überzegung gelangt, dass zumindest in diesem Fall die Nachteile (lokales Bearbeiten der Struktur) nicht durch die Vorteile (komfortableres UI) aufgewogen werden.

Serverseitiges CMS

Damit bleibt nur die Variante des serverseitigen CMS. Für den Umfang der Seite vielleicht ein wenig überdimensional. Aber immerhin kann man den Vorteil der Dynamik dann ja auch nutzen.
In diesem Bereich habe ich mich nicht mehr umgesehen, weil ich dbzgl. schon vor langer Zeit die Wahl getroffen hatte. Und zwar für Umbraco.

Umbraco

Die Wahl auf Umbraco fiel damals aus folgenden Gründen:

  1. Die Oberfläche zur Verwaltung und auch zur Pflege der Inhalte ist dank AJAX bereits sehr komfortabel.
  2. Klare und einfache Struktur der Oberfläche bzw. dem zugrundeliegenden Konzept.
  3. Das System ist extrem flexibel. Eine klare Trennung zwischen Struktur und Inhalt mit zusätzlicher Möglichkeit verschiedene Präsentatoren (Templates) zu verwenden und diese auch zu verschachteln.
  4. Ist in Microsoft .NET realisiert und verwendet den Microsoft SQL Server, was meinem gewohnten Arbeitsumfeld entspricht und mir als Software Entwickler somit sehr entgegenkommt. Obwohl ich bis dato keine Notwendigkeit hatte, diese Tatsache für mich zu nutzen. Ich konnte bisher alles mit den Bordmitteln des Systems und extra Packages lösen.
 
Beim Realisieren der Webseite war ich dann erneut begeistert wie einfach und schnell das mit Umbraco umgesetzt werden konnte.
Für die Grundstruktur habe ich vielleicht 25 Minuten benötigt. Die Details beim Design sind da eher ein Aufwand, aber das hat ja nichts mit dem CMS zu tun.
 
Es gibt - wie soll es anders sein - eine unüberschaubare Menge an CMS am Markt, die sich in unterschiedlichsten Kritieren unterscheiden. Die Wahl ist da sicherlich nicht einfach. Da sollte im Vorfeld auch sehr genau definiert werden, was das System leisten soll und welche Anforderungen in Zukunft zu erwarten sind. Zum Vergleich der Systeme gibt es verschiedene Websites allerdings sollte auf jeden Fall deren Aktualität der Informationen überprüft werden.