XAML-Kolumne: WPF und Windows-Apps

XAML-Tipp: WPF: UI-Debugging-Erweiterungen
Kommentare

In der Kolumne „XAML Expertise“ präsentiert Gregor Biswanger Top-How-tos zum Thema XAML. Einsteiger und fortgeschrittene XAML-Experten sollen hier durch geballtes Wissen gesättigt werden. Heute gibt es folgende Expertise: WPF: UI-Debugging-Erweiterungen.

Wie bereits erwähnt, bietet Visual Studio 2015 einige neue UI-Debugging-Möglichkeiten. Unabhängig davon hat das WPF-Produktteam weitere Anliegen von XAML-Entwicklern gesammelt, darunter die nachfolgenden:

  • Die Möglichkeit, eine bereits installierte oder in Entwicklung befindliche App zur Laufzeit inspizieren zu können
  • Eine „Up-to-date“-Darstellung des Visual Tree
  • Die Möglichkeit, Elemente zur Laufzeit selektieren zu können
  • Die Möglichkeit, jedes im Visual Tree dargestellte Element lokalisieren und selektieren zu können
  • Ein Befehl, um ein Element im XAML-Code zu finden
  • Eine komplette Liste aller Eigenschaften eines ausgewählten Elements, basierend darauf, wo die Eigenschaft gesetzt wurde (lokal, in einem Style etc.)
  • Die Möglichkeit, jeden Setter eines Properties unabhängig vom Gültigkeitsbereich ändern zu können
  • Ein Befehl, der es ermöglicht, direkt zu der Stelle zu springen, an der ein Property deklariert wurde, wenn es von XAML kommt
  • Eine Option, Veränderungen im Debug-Modus konstant an XAML weiterzuleiten

WPF: UI-Debugging-Erweiterungen

Anhand der gesammelten Rückmeldungen entstand die neue UI-Debugging-Helper-Klasse VisualDiagnostics. Diese gibt es ab .NET Framework 4.6. Die statische Klasse bietet ein VisualTreeChanged-Event und eine GetXamlSourceInfo-Methode. Die Funktionalität wird nur zur Verfügung gestellt, wenn die Library erkennt, dass ein Debugger an den aktuellen Prozess angehängt wurde. Wie die beiden Namen bereits verraten, kann der XAML-Prozess dadurch zur Laufzeit noch genauer beobachtet und analysiert werden.

Das folgende Beispiel demonstriert den genauen Mehrwert. Beim Klick auf den Add Data-Button soll eine ObservableCollection mit einem weiteren Wert gefüllt werden. Obwohl das Data Binding keine Fehler aufweist, wird auf der Oberfläche nichts sichtbar. Jetzt zweifelt natürlich der XAML-Entwickler, ob das Data Binding auch wirklich korrekt ausgeführt wird. Im ViewModel wird daher zum Testen das VisualTreeChanged-Event registriert.

Wird jetzt der Button angeklickt, zeigt das Ausgabefenster ein paarmal die Information Add an. Das bestätigt, dass der XAML-Parser nun einige Elemente erzeugt hat und das Data Binding korrekt war. Beim genaueren Hinsehen wird klar, weshalb die Elemente nicht sichtbar wurden. Das TextBlock-Steuerelement vom DataTemplate hat mit 0 px eine falsche Höhe. Natürlich ist das genannte Beispiel ein einfaches, allerdings kann es bei größeren Anwendungen oft eine Menge Zeit einsparen. Der Beispielcode dazu steht unter Listing 1 und 2.

Software Architecture Summit 2017

The Core of Domain-Driven Design

mit Carola Lilienthal (Workplace Solutions)

Distributed Systems

mit Kyle Kingsbury (Independent Consultant)

Listing 1: Die Elemente der „ListView“ sind nicht sichtbar

 
<Window.Resources>
  <viewModels:MainViewModel x:Key="MainViewModel" />
  <DataTemplate x:Key="DataSampleTemplate">
    <TextBlock Text="{Binding}" Height="0"></TextBlock>
  </DataTemplate>
</Window.Resources>
<Grid DataContext="{StaticResource MainViewModel}">
  <Grid.RowDefinitions>
    <RowDefinition Height="275*"/>
    <RowDefinition Height="50"/>
  </Grid.RowDefinitions>
  <ListView ItemsSource="{Binding DataCollection}" ItemTemplate="{StaticResource DataSampleTemplate}"/>
  <Button Grid.Row="1" Content="Add Data">
    <i:Interaction.Triggers>
      <i:EventTrigger EventName="Click">
        <ei:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="AddData"/>
      </i:EventTrigger>
    </i:Interaction.Triggers>
  </Button>
</Grid>

Listing 2: Mit „VisualTreeChanged“-Event beobachten, ob XAML-Parser aktiv wurde


public class MainViewModel
{
  public ObservableCollection DataCollection { get; set; }

  public MainViewModel()
  {
    DataCollection = new ObservableCollection();
    System.Windows.Diagnostics.VisualDiagnostics.VisualTreeChanged += OnVisualTreeChanged;
  }

  private void OnVisualTreeChanged(object sender, VisualTreeChangeEventArgs e)
  {
    Debug.WriteLine(e.ChangeType.ToString());
  }

  public void AddData()
  {
    DataCollection.Add("Hello World");
  }
}
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -