ListCollectionView

WPF_logo

In einem Kundenprojekt gab es die Anforderung die Daten aus einem DataGrid in der vom Anwender sortierten Reihenfolge zu drucken. Üblicherweise bindet man in einer WPF-Anwendung (MVVM) das DataGrid an die Instanz einer ObservableCollection. Eine gebundene ObservableCollection hat aber leider den Nachteil, dass sie vom Sortieren durch den Anwender (z.B. durch Click im Spaltenheader) nichts mitbekommt. D.h. die ursprüngliche Reihenfolge der Items in der ObservableCollection bleibt erhalten. Abhilfe schafft hier die Klasse ListCollectionView. Man erzeugt sich einfach eine neue Instanz einer ListCollectionView in dem man beim Konstruktor einfach die Instanz der ObservableCollection (oder einer Liste wie im Beispielprojekt) übergibt und bindet diese neue Instanz an das DataGrid. Wie man leicht mit einer Foreach-Schleife feststellen kann, entspricht die Reihenfolge der Items dann der Reihenfolge im DataGrid.

Hier ein Beispielprojekt mit freundlicher Unterstützung von Thomas Sobizack.

Weitere Infos z.B. unter http://weblogs.asp.net/monikadyrda/wpf-listcollectionview-for-sorting-filtering-and-grouping

 

Code Contracts

CodeContracts verwendet man zur Überprüfung von Parametern vor der eigentlichen Methodenausführung. Zunächst sollte das erforderliche Visual Studio AddIn (von Microsoft) installiert werden.  Nach der Installation erhält man unter den Projekteigenschaften eine neue Karteikarte Code Contracts:

CodeContracts1

Dort kann man sowohl das Static- als auch das Runtime-Checking aktivieren. Die statische Überprüfung wird unmittelbar nach dem Kompilieren ausgeführt und kann Probleme frühzeitig erkennen. Bei aktiviertem Runtime-Checking (z.B. im Debug -Modus) werden zur Laufzeit Exceptions geworfen, wenn gegen den Vertrag verstoßen wird. Ist die Runtime -Überprüfung ausgeschaltet (z.B. im Release-Modus), wird der Code ignoriert. Das führt natürlich zu einer verbesserten Performance. Im Code sieht das im einfachsten Fall so aus:

CodeContracts2

Bei aktivierter statischer Überprüfung werden dann folgende Fehler ausgegeben:

CodeContracts3

Weitere Infos unter:

http://www.codeproject.com/Articles/103779/Introducing-Code-Contracts

und

https://msdn.microsoft.com/de-de/library/system.diagnostics.contracts.contract%28v=vs.100%29.aspx

 

 

 

My “holy” ten commandments of software development

moses.gebote6

1. Learn programming language as good as possible!

2. Use a style guide!

3. Use code analysis and profiling tools!

4. Apply clean code developer rules!

5. Apply common design patterns!

6. Write unit tests!

7. Apply the agile software development methodology

8. Use a source code control

9. Meet colleagues for code reviews!

10. Visit lectures and conferences!

 

And another tip:

Never be satisfied with ‘good’ code! There is always room for improvement!

Windows Service Status

Service

Das Microsoft .Net Framework bietet eine einfache Möglichkeit festzustellen, ob ein bestimmter Windows Dienst gestartet ist und läuft.

C# Beispielcode:

(Verweis auf System.ServiceProcess muss vorab eingefügt werden)

using System;
using System.ServiceProcess;

namespace IsServiceRunning
{
  public class Program
  {
    public static void Main(string[] args)
    {
      const string serviceName = "Windows Search";
      Console.WriteLine("Service '{0}' running: {1}", serviceName, IsRunning(serviceName).ToString());
      Console.ReadLine();
    }

    /// <summary>
    /// windows service running ?
    /// </summary>
    /// <param name="serviceName">service name</param>
    /// <returns>true or false</returns>
    private static bool IsRunning(string serviceName)
    {
      try
      {
        ServiceController sc = new ServiceController(serviceName);
        return sc.Status == ServiceControllerStatus.Running;
      }
      catch
      {
        return false;
      }
    }
  }
}

Entsprechenden VB-Code findet man hier: http://dotnet-snippets.de/snippet/pruefen-ob-ein-dienst-gestartet-ist/157

Windows Store App “Clean Code Developer”

CCD

An dieser Stelle möchte ich auf die kostenlose Windows Store App “Clean Code Developer” von der generic.de Software Technologies AG verweisen. Die Anwendung teilt den gesamten Stoff in Schwierigkeitsgrade von “Schwarzer Grad” bis “Weißer Grad” ein. Der Stoff wird dadurch für den Anfänger in gut verdauliche Häppchen gestückelt. Regeln und Prinzipien werden vorgestellt. Der fortgeschrittene Entwickler wird natürlich auch an vielen Stellen sagen: “Das haben wir doch immer schon so gemacht!”. Trotzdem lohnt sich ein Blick denn es macht einfach Spaß zwischendurch einfach mal kurz reinzuschauen.

VirtualizingWrapPanel

WPF besitzt mit dem VirtualizingStackPanel und dem DataGridCellsPanel zwei Subklassen, die von der abstrakten Klasse VirtualizingPanel abgeleitet sind. Das VirtualizingStackPanel wird in der Regel innerhalb von anderen Steuerelementen wie z.B. der ListBox oder einem ListView zum Anordnen und damit zur Anzeige der ListItems verwendet. Warum wird dort kein normales Stackpanel verwendet? Die Antwort ist relativ einfach: Aus Performancegründen. Stellen Sie sich eine ListView mit einigen tausend Einträgen vor. Bei einem VirtualizingStackPanel werden nur die Einträge erstellt, die im aktuell sichtbaren Bereich des ListViews liegen. Erst wenn der Anwender mit dem Scrollen beginnt werden die anderen Einträge erstellt. Bei einem normalen StackPanel würden zunächst alle Items (also auch die zunächst nicht sichtbaren) erstellt. Das führt in der Regel zu deutlichen Performanceproblemen. Unter Umständen kann der Bildschirm mehrere Minuten einfrieren bevor alle Elemente gerendert sind. (Das DataGridCellsPanel arbeitet analog wie das VirtualizingStackPanel. Allerdings kommt es lediglich intern im DataGrid zum Einsatz.)

In einem Kundenprojekt habe ich nun analog ein VirtualizingWrapPanel benötigt, da ich eine größere Anzahl von Items innerhalb eines ListViews in Form eines WrapPanels darstellen wollte. Leider stellt einem das .Net Framework dafür out of the box keine entsprechende Klasse zur Verfügung. Abhilfe verspricht hier das folgende Projekt: http://www.codeproject.com/Articles/75847/Virtualizing-WrapPanel. Das Projekt liefert ein solches frei verfügbares VirtualizingWrapPanel inklusive SourceCode. Leider haben meine Tests gezeigt, dass dieses Panel zumindest für meine Ansprüche nicht performant genug ist. Beim Vergrößern eines Fensters ruckelte es doch ziemlich stark, wenn die Einträge neu umgebrochen werden müssen. Beim Scrollen gibt es teilweise den gleichen Effekt. Außerdem funktionierte es in meinem Anwendungsfall nicht ohne Probleme. Ab und an kam es leider zu Abstürzen bzw. unbehandelten Exceptions.

Die einzige vernünftige Lösung bietet aktuell meines Wissens nach die Firma Binarymission (http://binarymission.co.uk/binaryvirtualizingwrappanelwpf.htm). Deren VirtualizingWrapPanel funktionierte in meinem Anwendungsfall ohne Probleme. Das Produkt ist aber leider kostenpflichtig!

Falls jemand eine bessere Lösung weiß, wäre ich für einen entsprechenden Hinweis sehr dankbar!

WPF Binding Converter

Das .Net-Framework kommt OFTB bereits mit einigen Konvertern daher: AlternationConverter, BooleanToVisibilityConverter, BorderGapMaskConverter, DataGridLengthConverter, MenuScrollingVisibilityConverter, ZoomPercentageConverter, JournalEntryListConverter, ProgressBarBrushConverter, ProgressBarHighlightConverter, JournalEntryUnifiedViewConverter (weitere Infos unter: http://asimsajjad.blogspot.de/2010/05/built-in-wpf-ivalueconverters.html)

Ein Konverter, den ich schon häufiger vermisst habe,  ist der BoolToOppositeBoolConverter-Converter, der einfach “True” in “False” konvertiert und umgekehrt: http://www.codeproject.com/Articles/24330/WPF-Bind-to-Opposite-Boolean-Value-Using-a-Convert

Weitere Konverter findet man hier: http://wpfconverters.codeplex.com/

VSTO AddIn – Installation

microsoft-office

Wie man ein VSTO Addin für alle Benutzer installiert wird hier im Detail beschrieben:

http://blogs.msdn.com/b/mshneer/archive/2007/09/04/deploying-your-vsto-add-in-to-all-users-part-i.aspx

http://blogs.msdn.com/mshneer/archive/2007/09/05/deploying-your-vsto-add-in-to-all-users-part-ii.aspx

FileSystemWatcher

Ein FileSystemWatcher in .Net kann unter Umständen auch mal seine Arbeit verweigern. Das kann sich zum Beispiel so auswirken, das die Software nicht mehr auf das Created-Ereignis reagiert. Wie in einem solchen Fall zu verfahren ist steht z.B. hier: http://stackoverflow.com/questions/6184115/filesystemwatcher-stops-catching-events