Archive

Posts Tagged ‘WPF’

WPF Databinding Probleme mit Snoop finden

January 15th, 2009 Bernd 4 comments

WPF Databindings werden häufig in XAML definiert. Da kann es schon mal vorkommen, daß sich der eine oder andere Tippfehler einschleicht – mit dem Ergebnis, daß das Binding nicht wie gewünscht funktioniert. Simples Beispiel:

<Window x:Class="DataBinding.Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:local="clr-namespace:DataBinding"
   Title="Binding error" Height="300" Width="300">

   <Window.Resources>
       <local:CompactDisc x:Key="myOneAndOnlyCD" Title="Images And Words" Artist="Dream Theater"/>
   </Window.Resources>

   <StackPanel>
       <TextBlock Text="{Binding Source={StaticResource myOneAndOnlyCD}, Path=Titel}"/>
       <TextBlock Text="{Binding Source={StaticResource myOneAndOnlyCD}, Path=Artist}"/>
   </StackPanel>
</Window>

 

CompactDisc ist die einfachste aller Klassen:

namespace DataBinding
{
   public class CompactDisc
   {
       public string Title { get; set; }
       public string Artist { get; set; }
   }
}

 

Wird dieser Code ausgeführt, wundert man sich, daß zwar der Künstlername angezeigt wird, aber der Titel nicht. Was ist passiert?

Hier kommt Snoop ins Spiel. Snoop ist eines der vielen kleinen Tools die dem WPF Entwickler das Leben leichter machen. Neben diversen anderen Features wie

  • den Visual Tree betrachten
  • Eigenschaften der Elemente im Visual Tree editieren
  • Routed Events verfolgen
  • Zoom der ausgewählten WPF Anwendung

kann das Tool auch Binding Fehler anzeigen.

Nach dem Start listet Snoop in einer Combobox alle WPF Applikationen auf, die momentan ausgeführt werden.

SnoopStartup

Man wählt die betreffende Applikation aus und mit einem Klick auf das Fernglas verbindet sich Snoop damit. Es öffnet sich ein weiteres Fenster in dem man sich den Details widmen kann:

 Snoop visual tree

Öffnet man nun die Combobox in der linken, oberen Ecke findet man den Eintrag “Visuals with binding errors”. Wählt man diesen aus, erhält man eine gefilterte Liste:

Snoop binding errors

In dem Properties Tab auf der rechten Seite wird nun die betroffene Eigenschaft rot eingefärbt. Ein Tooltip zeigt die komplette Fehlermeldung:

System.Windows.Data Error: 39 : BindingExpression path error: ‘Titel‘ property not found on ‘object’ ”CompactDisc’ (HashCode=33736294)’. BindingExpression:Path=Titel; DataItem=’CompactDisc’ (HashCode=33736294); target element is ‘TextBlock’ (Name=”); target property is ‘Text’ (type ‘String’)

Es hat sich also ein Tippfehler bei dem ersten Binding gegen die Eigenschaft “Title” eingeschlichen.

Ok, ok. Den Fehler sieht man auch sofort, wenn die Anwendung im Debugmodus aus dem Visual Studio gestartet wird. Dort wird der gleiche Fehlertext im Output Fenster angezeigt. Aber ich wollte halt meine Begeisterung über Snoop teilen…

Um auch komplizierteren Bindingproblemen auf die Spur zu kommen gibt es seit .Net 3.5 an der PresentationTraceSources Klasse die Attached Property TraceLevel. Bea Stollnitz zeigt hier wie man sie einsetzt (und gibt noch ein paar weitere Tipps zu Debugging von WPF Databinding).

Categories: Softwareentwicklung Tags: ,

Debugging von WPF Custom Markup Extensions im Design Mode

January 12th, 2009 Bernd No comments

In einem der letzten Beiträge (link) bin ich über einen Umweg bei den Markup Extensions gelandet. Selbst geschriebene Markup Extensions (Custom Markup Extensions) können durchaus komplexen Code ausführen. Dabei sollte man beachten, dass dieser Code auch im Kontext eines Designer funktioniert. Da kann es hilfreich sein, die Extension auch in diesem Kontext zu debuggen.

Der Code der zu debuggenden Markup Extension wird in diesem Fall von dem Visual Studio ausgeführt, in dem die Markup Extension verwendet wird. D.h. der Debugger (z.B. ein zweites Visual Studio) muss an diese Instanz angehängt werden.

attachtovisualstudio

Man wählt also in Visual Studio (2) im Menü den Eintrag “Tools –> Attach to Process…” aus

attachtoprocess

und wählt dann aus der Liste der angezeigten Prozesse die entsprechende Instanz des anderen Studios (1) aus. Als nächstes können wir das Sourcefile der zu debuggenden Markup Extension im zweiten Studio öffnen und einen Breakpoint setzen. Sobald nun das .xaml File mit der betreffenden Markup Extension im Design Modus betrachtet wird, schlägt der Breakpoint an und die Fehlersuche kann beginnen.

breakpointinmarkupextension

Categories: Softwareentwicklung Tags:

Syndicated Client Experiences (SCE) Starter Kit

January 8th, 2009 Bernd No comments

Microsoft hat ein neues Goodie für WPF Entwickler zur Verfügung gestellt. Das Syndicated Client Experiences Starter Kit. Wow, was für ein Name! Das Starter Kit besteht aus einem Visual Studio Projekt Template für C# und einer Handvoll zusätzlicher Assemblies die zum Erstellen eines SCE Projekts benötigt werden. Eine SCE Applikation nutzt RSS um mit Daten gefüttert zu werden, speichert diese lokal auf der Clientmaschine um sie dann dem Benutzer in möglichst ansprechender Weise zu präsentieren.

Es wird auf der Seite auf verschiedene Anwendungen verwiesen, die mit dem Starter Kit entwickelt wurden. Das Highlight dürfte aber photoSuru sein:

photoSuru

Die Applikation zeigt eine breite Palette von WPF Features: flexibles Layouting, Pixel Shader für Bildeffekte, Animationen usw. Eine schönes Beispiel wie ich finde, welches die Fähigkeiten von WPF sehr gut demonstriert.

Und nicht zu vergessen, der Sourcecode für die Applikation steht bei Windowsclient.net zum Download bereit!

Mehr Infos gibts hier:

Categories: Neuigkeiten Tags:

WPF Code im Kontext eines Designers

January 4th, 2009 Bernd No comments

Manchmal ist es hilfreich zu wissen, ob eine Stück WPF Code gerade im Design Modus von Visual Studio läuft oder nicht.

Beim Experimentieren mit Caliburn bin ich auf ein Problem mit dessen “ResolveExtension” gestoßen. Hierbei handelt es sich um eine Custom Markup Extension, die auf den für Caliburn konfigurierten DI-Container zugreift. Wird nun eine XAML Datei, welche diese Markup Extension verwendet, im Design Modus betrachtet, wird diese Markup Extension ausgeführt. Caliburn wirft dann eine Exception, da der DI-Container auf den zugegriffen werden soll nicht initialisiert ist. Das hat zur Folge, dass diese Datei nicht im Designer verwendet werden kann.

Eine mögliche Lösung dieses Problems besteht darin, im Code der Markup Extension zu überprüfen ob man sich gerade im Design Modus befindet. Dazu bietet .Net im Namespace System.ComponentModel die Klasse DesignerProperties. Mit folgendem Aufruf erfolgt die Überprüfung:

if( DesignerProperties.GetIsInDesignMode( new DependencyObject() ) )
{
    // tu was
}

Im Falle von Caliburn sieht dann die ProvideValue Methode der ResolveExtension so aus:

public override object ProvideValue( IServiceProvider serviceProvider )
{
    if( DesignerProperties.GetIsInDesignMode( new DependencyObject() ) )
    {
        return null;
    }

    if( string.IsNullOrEmpty( Key ) )
    {
        return DI.Container.Resolve( Type );
    }
    return Type == null ? DI.Container.Resolve( Key ) : DI.Container.Resolve( Type, Key );
}

Das Ganze funktioniert sowohl für den Visual Studio Designer als auch für Expression Blend.

Categories: Softwareentwicklung Tags: