XAML-Kolumne: WPF und Windows-Apps

XAML-Tipp: WPF: UI-Debugging-Erweiterungen
Keine 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.

ML Conference 2021

Efficient Transformers

Christoph Henkelmann, DIVISIO

Enhancing Page Visits by Topic Prediction

Dieter Jordens, Continuum Consulting NV

Machine Learning on Edge using TensorFlow

Håkan Silfvernagel, Miles AS

ML & Python Summit 2021

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

Abonnieren
Benachrichtige mich bei
guest
0 Comments
Inline Feedbacks
View all comments
X
- Gib Deinen Standort ein -
- or -