Dieser Artikel wurde maschinell übersetzt.

Die Benutzeroberfläche und ihre Grenzen

Die fließende Benutzeroberfläche in Silverlight 4

Charles Petzold

Downloaden des Codebeispiels

Charles PetzoldDer Begriff “ Pneumatik / UI ” kurzem verfügt über gemeinsame UI-Entwurf Techniken beschrieben, die zu vermeiden, dass visuelle Objekte plötzlich holt in der Ansicht oder von einer Position zu einer anderen springen.Stattdessen Objekte visuell Pneumatik /, mehr sicheres Eingänge und Übergänge – manchmal Wenn entstehende aus Nebel oder gleitende in Ansicht.

In den letzten beiden Ausgaben dieser Rubrik habe ich einige Techniken Pneumatik / UI auf Ihre eigene Implementierung erläutert. Ich wurde teilweise durch die bevorstehende Einführung einer Flüssigkeit Benutzeroberflächenfunktion in Silverlight 4 anregte. Nun, da Silverlight 4 offiziell veröffentlicht hat, ist, was ich werde hier behandelt werden. Silverlight-4 Foray in Flüssigkeit Benutzeroberfläche ziemlich spezieller beschränkt ist – es ist beschränkt auf das Laden und Entladen von Elementen in einem Listenfeld –, aber es gibt uns einige wichtige Hinweise zum Verfahren zur Pneumatik / Benutzeroberfläche mit unseren eigenen Implementierungen zu erweitern. Mehr Pneumatik / UI-Verhaltensweisen sind in Expression Blend 4 verfügbar.

Vorlagen und VSM

Wenn Sie genau, wo sich das neue Feature der flüssige Benutzeroberfläche in Silverlight 4 nicht kennen, können Sie viele Stunden suchen. Es ist keine Klasse. Es ist keine Eigenschaft. Es ist keine Methode. Es ist kein Ereignis. Es ist tatsächlich als drei neue visuelle Zustände ListBoxItem-Klasse implementiert. Abbildung 1 zeigt die Dokumentation für die Klasse mit etwas anders angeordnet, in Übereinstimmung mit den Gruppennamen TemplateVisualState Attribut Elemente.

Abbildung 1 die Dokumentation ListBoxItem-Klasse

[TemplateVisualStateAttribute(Name = "Normal", GroupName =  
  "CommonStates")]
[TemplateVisualStateAttribute(Name = "MouseOver", GroupName = 
  "CommonStates")]
[TemplateVisualStateAttribute(Name = "Disabled", GroupName = 
  "CommonStates")]
[TemplateVisualStateAttribute(Name = "Unselected", GroupName = 
  "SelectionStates")]
[TemplateVisualStateAttribute(Name = "Selected", GroupName =  
  "SelectionStates")]
[TemplateVisualStateAttribute(Name = "SelectedUnfocused", GroupName = 
  "SelectionStates")]
[TemplateVisualStateAttribute(Name = "Unfocused", GroupName = 
  "FocusStates")]
[TemplateVisualStateAttribute(Name = "Focused", GroupName = 
  "FocusStates")]
[TemplateVisualStateAttribute(Name = "BeforeLoaded", GroupName = 
  "LayoutStates")]
[TemplateVisualStateAttribute(Name = "AfterLoaded", GroupName = 
  "LayoutStates")]
[TemplateVisualStateAttribute(Name = "BeforeUnloaded", GroupName =  
  "LayoutStates")]
public class ListBoxItem : ContentControl

Visual State Manager (VSM) ist eine der wichtigsten Änderungen, die auf Silverlight vorgenommen werden, wie es von Windows Presentation Foundation angepasst wird, war. In WPF kann einen Stil oder eine Vorlage (fast immer in XAML definiert) namens Trigger-Elemente enthalten. Diese Trigger werden entweder eine Eigenschaft oder ein Ereignis erkennen und initiieren Sie eine Animation oder eine Änderung einer anderen Eigenschaft definiert.

Eine Formatdefinition für ein Steuerelement kann z. B. einen Trigger für die IsMouseOver-Eigenschaft enthalten, die den Hintergrund des Steuerelements auf ein blauer Pinsel, festlegt Wenn die Eigenschaft auf true festgelegt ist. Oder ein Trigger für die MouseEnter- und MouseLeave-Ereignisse kann beim Auftreten dieser Ereignisse ein paar kurze Animationen initiieren.

In Silverlight wurden Trigger größtenteils banished und durch die VSM teilweise einen strukturierten Ansatz für die Eigenschaften eines Steuerelements zur Laufzeit dynamisch geändert sowie teilweise Umgang mit den verschiedenen Kombinationen von Möglichkeiten zu vermeiden, wenn mehrere Trigger definiert werden ersetzt. VSM gilt eine solche Verbesserung gegenüber Trigger werden, dass er Teil der WPF in Microsoft .NET Framework, 4 geworden ist.

Wie Sie sehen können, in Abbildung 1 ListBoxItem-Steuerelement unterstützt die 11 visuelle Zustände, aber Sie sind in vier Gruppen zugeteilt. Innerhalb jeder Gruppe ist nur einen visuellen Zustand zu einem beliebigen Zeitpunkt aktiv. Diese einfache Regel werden deutlich reduziert die Anzahl der möglichen Kombinationen. Beispielsweise müssen Sie herausfinden, wie die ListBoxItem angezeigt werden soll, wenn der Mauszeiger über ein Element ausgewählten aber unfocused ist nicht, unabhängig von den anderen jeder Gruppe verarbeitet werden kann.

Der Code Teil ListBoxItem ist verantwortlich für die visuelle Zustände durch Aufrufen der statischen VisualStateManager.GoToState-Methode ändern. Die Steuerelementvorlage für ListBoxItem ist verantwortlich für die Reaktion auf diese visuelle Zustände. Die Vorlage reagiert auf Änderungen bestimmten visuellen Zustand mit einem einzigen Storyboard, enthält ein oder mehrere Animationen, die auf Elemente in der visuellen Struktur. Wenn Sie das Steuerelement auf eine Änderung visuellen Zustand ohne eine Animation sofort reagieren möchten, können Sie einfach die Animation mit einer Dauer von 0 definieren. Aber warum kümmern? Es ist genau so einfach zu verwenden eine Animation Darstellungen des Steuerelements weitere Flüssigkeit beitragen.

Der neue visuelle Zustände für die Unterstützung der flüssigen Benutzeroberfläche sind BeforeLoaded, AfterLoaded und BeforeUnloaded, Teil der Gruppe LayoutStates. Durch Zuordnen von Animationen auf diese visuelle Zustände, können Sie Elemente in Ihrem Listenfeld-Steuerelement ausblenden, stellen oder wachsen oder glide angezeigt, wenn Sie zuerst das Listenfeld-Steuerelement hinzugefügt haben und etwas anderes tun, wenn Sie aus dem Listenfeld entfernt sind.

Anpassen der Vorlage ListBoxItem

Die meisten Programmierer werden wahrscheinlich die Flüssigkeit Benutzeroberflächenfunktion von ListBoxItem über Expression Blend zugreifen, aber ich werde zeigen, wie Sie dafür direkt im Markup.

Die Standard-Steuerelementvorlage für ListBoxItem hat keine Animationen, die visuelle Zustände in der Gruppe LayoutStates zugeordnet. Dies ist Ihre Aufgabe. Leider kann nicht einfach “ Ableiten von ” vorhandene ListBoxItem-Vorlage und ergänzen Sie mit Ihrer eigenen Daten. Sie müssen die gesamte Vorlage in Ihrem Programm einfügen. Glücklicherweise ist es lediglich kopieren und einfügen. Suchen Sie in der Silverlight-4-Dokumentation in der Controls-Abschnitt und dann der Anpassung und Control Styles und Vorlagen, und ListBox-Stile und Vorlagen. Finden Sie die Standard-Formatvorlagendefinition für ListBoxItem (einschließlich die Vorlagendefinition) im Markup, die beginnt:

<Style TargetType="ListBoxItem">

Unter dem Setter-Element für die Template-Eigenschaft wird die gesamte ControlTemplate verwendet, um eine visuelle Struktur für jeden ListBoxItem erstellen angezeigt. Der Stamm der visuellen Struktur ist eine einzelne Zelle am Raster. Das Markup VSM belegt einen großen Teil der Vorlage am oberen Rand der Raster-Definition. Sind Sie am unteren Rand der eigentliche Inhalt der Raster: drei Rechteck-Shapes (2 gefüllt und eine gerade gestrichelt) und ein ContentPresenter-Element, etwa so:

<Grid ... >
  ...  <Rectangle x:Name="fillColor" ... />
  <Rectangle x:Name="fillColor2" ... />
  <ContentPresenter x:Name="contentPresenter" ... />
  <Rectangle x:Name="FocusVisualElement" ... />
</Grid>

Die ersten beiden ausgefüllten Rectangle-Objekte werden zur Hintergrundfarbe (bzw.) für die Maus über und Auswahl zu ermöglichen. Die dritte zeigt eine gestrichelte Rechteck Eingabefokus an. Die Sichtbarkeit der diese Rechtecke wird durch das Markup VSM gesteuert. Beachten Sie, wie jede Gruppe visuelle eigenes Element bearbeiten abruft. Die ContentPresenter hostet das Element, wie er im Listenfeld angezeigt wird. Im Allgemeinen ist der Inhalt der ContentPresenter einen anderen visuellen Struktur definiert, die in einem DataTemplate, die ItemTemplate-Eigenschaft von ListBox festgelegt ist.

Das Markup VSM besteht aus Elementen des Typs VisualStateManager.VisualStateGroups, VisualStateGroup und VisualState, alle mit einer XML-Namespacepräfix des “ Vsm ”. In früheren Silverlight-Versionen war es notwendig, eine Namespacedeklaration für das Präfix definieren:

xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"

Jedoch in Silverlight 4 können einfach Vsm-Präfixe gelöscht und vergessen Sie diese Namespacedeklaration. Änderungen an dieser Vorlage vornehmen, sollten Sie den gesamten Bereich von Markup in ein Resource-Abschnitt einer XAML-Datei kopieren und ihm einen Namen:

<Style x:Key="listBoxItemStyle" TargetType="ListBoxItem">
  ... </Style>

Dann legen Sie dieses Format ItemContainerStyle-Eigenschaft des Listenfeld-Steuerelements:

<ListBox ... ItemContainerStyle="{StaticResource listBoxItemStyle}" ....

“ Elementcontainer ” ist das Objekt, das Listenfeld-Steuerelement erstellt wird, als Wrapper für jedes Element im ListBox, und ein Objekt vom Typ ListBoxItem.

Sobald Sie diese ListBoxItem Stil- und in Ihrem Programm haben, können Sie Änderungen daran vornehmen.

Einblenden, ausblenden aus

Let’s finden Sie unter Funktionsweise im Kontext eines Programms einfache Demo. Der herunterladbare Code für diesen Artikel ist eine Lösung, die mit dem Titel „ FluidUserInterfaceDemo. Es besteht aus zwei Programmen charlespetzold.com/silverlight/FluidUserInterfaceDemo-aus meiner Website ausgeführt werden kann. Beide Programme sind auf einer HTML-Seite, jeden belegten das gesamte Browserfenster.

Das erste Programm ist FluidListBox. Visuell, besteht es ein Listenfeld und zwei Schaltflächen zum Hinzufügen und Entfernen von Elementen. Ich habe die gleiche Sammlung von Besorgungs-erzeugen verwendet, die ich in meinem letzten beiden Spalten verwendet haben, damit MainPage.xaml außerdem ein DataTemplate ProduceDataTemplate benannt enthält.

Ich habe entschieden, ich wollte, starten Sie einfach, und die Elemente in der Ansicht ausgeblendet werden, wenn das Listenfeld-Steuerelement hinzugefügt haben, und ausbleichen, wenn Sie gerade entfernt haben. Dies umfasst die Opacity-Eigenschaft des Rasters, die bildet den Stamm der visuellen Struktur animieren. Das Ziel einer Animation darstellen, die Raster einen Namen benötigt:

<Grid Name="rootGrid" ...>

Fügen Sie zuerst ein neues VisualStateGroup innerhalb der Tags VisualStateManager.VisualStateGroups:

<VisualStateGroup x:Name="LayoutStates">  ...
</VisualStateGroup>

Ist das Markup für die BeforeLoaded, AfterLoaded und BeforeUnloaded Zustände in der Gruppe LayoutStates, wohin fließt.

Der Fade-in ist die einfachere der zwei Aufträge. Wenn ein Element in der visuellen Struktur zuerst hinzugefügt wird, hat er als in der visuellen Struktur “ geladen ” bezeichnet. Vor, geladen wird, das Element hat einen visuellen Zustand des BeforeLoaded und dann der visuelle Zustand AfterLoaded wird.

Es gibt mehrere Möglichkeiten zum Definieren der Fade-in. Die erste erfordert Initialisierung der Deckkraft auf 0 im Raster-Tag:

<Grid Name="rootGrid" Opacity="0" ... >

Sie geben dann eine Animation für den AfterLoaded Zustand im Laufe von 1 Sekunde die Opacity-Eigenschaft auf 1 zu erhöhen:

<VisualState x:Name="AfterLoaded">
  <Storyboard>
    <DoubleAnimation Storyboard.TargetName="rootGrid"
                     Storyboard.TargetProperty="Opacity"
                     To="1" Duration="0:0:1" />
  </Storyboard>
</VisualState>

Oder übernehmen Sie den Standardwert von 1 die Durchlässigkeit Raster und Animationen für BeforeLoaded und AfterLoaded bereitzustellen:

<VisualState x:Name="BeforeLoaded">
  <Storyboard>
    <DoubleAnimation Storyboard.TargetName="rootGrid"
                     Storyboard.TargetProperty="Opacity"
                     To="0" Duration="0:0:0" />
  </Storyboard>
</VisualState>
                                    
<VisualState x:Name="AfterLoaded">
  <Storyboard>
    <DoubleAnimation Storyboard.TargetName="rootGrid"
                     Storyboard.TargetProperty="Opacity"
                     To="1" Duration="0:0:1" />
  </Storyboard>
</VisualState>

Beachten Sie, dass die Dauer des BeforeLoaded Status 0 ist effektiv nur die Opacity-Eigenschaft auf 0 festgelegt. Mithilfe einer ganzen Storyboard und DoubleAnimation nur zum Festlegen einer Eigenschaft wie übertrieben mag, aber es veranschaulicht auch die Flexibilität von Animationen. Der Aufwand ist eigentlich nicht sehr stark.

Das Verfahren, das ich persönlich bevorzuge, hauptsächlich, weil er am einfachsten ist, besteht darin, übernehmen Sie den Standardwert von 1 die Opacity-Eigenschaft des Rasters und bieten nur eine Animation für den AfterLoaded Zustand mit einem Wert angegeben werden, anstatt einen Wert an:

<VisualState x:Name="AfterLoaded">
  <Storyboard>
    <DoubleAnimation Storyboard.TargetName="rootGrid"
                     Storyboard.TargetProperty="Opacity"
                     From="0" Duration="0:0:1" />
  </Storyboard>
</VisualState>

Jetzt geht die Animation vom Wert von 0 auf dessen Basis Wert 1 ist. Diese Technik identisch können mit dem Status BeforeLoaded. Aber achten: BeforeLoaded Zustand tritt ein, nachdem die ListBoxItem erstellt und initialisiert wird, jedoch bevor der visuellen Struktur hinzugefügt wird, an welcher Stelle der AfterLoaded Zustand eintritt. Das ist nur ein WINZIGER ZWISCHENRAUM Zeitraum. Sie erhalten in Schwierigkeiten, wenn Sie eine Animation für BeforeLoaded definieren, aber auch ein leeres VisualState Tag für AfterLoaded definieren:

<VisualState x:Name="BeforeLoaded">
  <Storyboard>
    <DoubleAnimation Storyboard.TargetName="rootGrid"
                     Storyboard.TargetProperty="Opacity"
                     From="0" Duration="0:0:1" />
  </Storyboard>
</VisualState>
                                    
<VisualState x:Name="AfterLoaded" />

Sobald das Element geladen wurde, wird das Storyboard für BeforeLoaded abgebrochen, und erhalten Sie keine Wirkung Fade-in. Stellen Sie jedoch dieses Markup arbeiten, wenn Sie auch Folgendes hinzufügen:

<VisualStateGroup.Transitions>
  <VisualTransition From="BeforeLoaded"
                    To="AfterLoaded"
                    GeneratedDuration="0:0:1" />
</VisualStateGroup.Transitions>

Eine Periode einsekündigen Übergang zwischen den BeforeLoaded und die AfterLoaded Zustände definiert. Dieser Übergangsphase kann die Animationsdauer BeforeLoaded abschließen, bevor der Zustand AfterLoaded deaktiviert wird.

Der Prozess Fade-out ist ziemlich einfach nicht. Wenn das Element wird aus dem Listenfeld entfernt werden soll, der Zustand BeforeUnloaded ist festgelegt, aber das Element wird dann sofort entfernt wird nicht so eine Animation, die Beginn sichtbar sein! Ich habe zwei Ansätze festgestellt, die funktionieren. Der erste definiert eine Animation für den Zustand BeforeUnloaded zusammen mit einem Übergang für diesen Zustand:

<VisualState x:Name="BeforeUnloaded">
  <Storyboard>
    <DoubleAnimation Storyboard.TargetName="rootGrid"
                     Storyboard.TargetProperty="Opacity"
                     To="0" Duration="0:0:1" />
  </Storyboard>
</VisualState>

<VisualStateGroup.Transitions>
  <VisualTransition From="AfterLoaded" 
                    To="BeforeUnloaded" 
                    GeneratedDuration="0:0:1" />
</VisualStateGroup.Transitions>

Der zweite Ansatz definiert ein leeres Tag für das Bundesland BeforeUnloaded und einer Animation für die VisualTransition:

<VisualStateGroup.Transitions>
  <VisualTransition From="AfterLoaded" 
                    To="BeforeUnloaded" 
                    GeneratedDuration="0:0:1">
    <Storyboard>
      <DoubleAnimation Storyboard.TargetName="rootGrid"
                       Storyboard.TargetProperty="Opacity"
                       To="0" Duration="0:0:1" />
    </Storyboard>
  </VisualTransition>
</VisualStateGroup.Transitions>

Abbildung 2 zeigt das abgeschlossene Markup für die Zustände AfterLoaded und BeforeUnloaded, wie Sie in der Vorlage ListBoxItem MainPage.xaml-Datei des Projekts FluidListBox angezeigt werden.

Abbildung 2 ein Auszug aus dem ListBoxItem-Vorlage in FluidListBox

<ControlTemplate TargetType="ListBoxItem">
  <Grid Name="rootGrid" Background="{TemplateBinding Background}">
    <VisualStateManager.VisualStateGroups>

      <!-- Additions to standard template -->
      <VisualStateGroup x:Name="LayoutStates">
                                    
        <VisualState x:Name="AfterLoaded">
          <Storyboard>
            <DoubleAnimation Storyboard.TargetName="rootGrid"
                             Storyboard.TargetProperty="Opacity"
                             From="0" Duration="0:0:1" />
          </Storyboard>
        </VisualState>
                                    
        <VisualState x:Name="BeforeUnloaded" />

          <VisualStateGroup.Transitions>
            <VisualTransition From="AfterLoaded" 
                              To="BeforeUnloaded" 
                              GeneratedDuration="0:0:1">
              <Storyboard>
                 <DoubleAnimation Storyboard.TargetName="rootGrid"
                                  Storyboard.TargetProperty="Opacity"
                                  To="0" Duration="0:0:1" />
              </Storyboard>
            </VisualTransition>
          </VisualStateGroup.Transitions>
        </VisualStateGroup>
        <!-- End of additions to standard template -->
            ...
  </Grid>
</ControlTemplate>

One more warning: By default, the ListBox stores its items in a VirtualizingStackPanel. This means the actual items and their containers aren't generated until they're required to be visually displayed. If you define an animation for the After-Loaded state, and then fill the ListBox up with items, the items will fade in as they're scrolled into view. This is probably undesirable. The easy solution is to replace the VirtualizingStackPanel with a regular StackPanel. The required markup on the ListBox is trivial:

<ListBox.ItemsPanel>
  <ItemsPanelTemplate>
    <StackPanel />
  </ItemsPanelTemplate>
</ListBox.ItemsPanel>

Erweitern von ItemsControl

Da die Flüssigkeit Benutzeroberflächenfunktion als visuelle Zustände auf ListBoxItem implementiert wird, ist es nicht in der ItemsControl verfügbar. Wie Sie wissen, ItemsControl einfach eine Auflistung von Elementen anzeigt und ermöglicht dem Benutzer, die durch diese navigieren. Es gibt kein Konzept für die Auswahl oder der Eingabefokus zwischen den Elementen. Aus diesem Grund ist ItemsControl eine besondere Klasse wie ListBoxItem zum Hosten der Elemente nicht erforderlich. Es wird nur ein ContentPresenter-Element verwendet. Da ContentPresenter von FrameworkElement anstatt von Control abgeleitet ist, keinen es eine Vorlage, in der das Verhalten der visuelle Zustände definieren.

Jedoch Möglichkeiten ist das Ableiten einer Klasse von ItemsControl ListBoxItem verwendet wird, um seine Elemente zu hosten. Dies ist tatsächlich sehr viel einfacher, als Sie annehmen können. Abbildung 3 wird der gesamten Code für FluidableItemsControl.

Abbildung 3 Die FluidableItemsControl-Klasse

using System.Windows;
using System.Windows.Controls;

namespace FluidItemsControl
{
  public class FluidableItemsControl : ItemsControl
  {
    public static readonly DependencyProperty ItemContainerStyleProperty =
      DependencyProperty.Register("ItemContainerStyle",
      typeof(Style),
      typeof(FluidableItemsControl),
      new PropertyMetadata(null));

    public Style ItemContainerStyle
    {
      set { SetValue(ItemContainerStyleProperty, value); }
      get { return (Style)GetValue(ItemContainerStyleProperty); }
    }

    protected override DependencyObject GetContainerForItemOverride()
    {
      ListBoxItem container = new ListBoxItem();

      if (ItemContainerStyle != null)
        container.Style = ItemContainerStyle;

      return container;
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
      return item is ListBoxItem;
    }
  }
}

Die entscheidende-Methode ist GetContainerForItemOverride. Diese Methode gibt das Objekt verwendet, um jedes Element umbrochen. ItemsControl gibt ContentPresenter, aber ListBox gibt ListBoxItem und, was FluidableItemsControl ebenfalls zurückgegeben wird. Diese ListBoxItem muss eine Formatvorlage zugewiesen haben, und aus diesem Grund FluidableItemsControl definiert außerdem die gleiche ItemContainerStyle-Eigenschaft als Listenfeld-Steuerelement.

Die Methode, die implementiert werden sollten, ist IsItemItsOwnContainerOverride. Wenn das Element in der ItemsControl bereits den gleichen Typ wie seines Containers (in diesem Fall ein ListBoxItem) ist, wird kein Grund, in einen anderen Container enthalten sein. Jetzt können Sie eine Formatdefinition ListBoxItem ItemContainerStyle-Eigenschaft des FluidableItemsControl festlegen. Die Vorlage in der Formatdefinition kann erheblich vereinfacht werden. Es muss Logik für die Maus über, Auswahl oder Eingabe Fokus, damit diese visuelle Zustände gelöscht werden können, sowie drei Rectangle-Objekte.

Das Programm FluidItemsControl zeigt das Ergebnis. Es ist ziemlich ähnlich wie FluidListBox jedoch alle ListBox Auswahl Logik nicht vorhanden ist. Der Standardbereich für ItemsControl-Element ist ein StackPanel, Vereinfachung einer anderen. Um diese Vereinfachungen auszugleichen, habe ich die Animationen für das Laden und Entladen von Elementen erweitert. Jetzt ist eine Animation auf die PlaneProjection Transformation, die erscheinen, als ob die Elemente in swiveling sind und aus der Ansicht.

Einschränkungen und Vorschläge

Auch mit der Funktion zum Definieren von Animationen auf Elemente in ein ItemsControl-Element oder einem Listenfeld-Steuerelement gibt es immer noch eine wichtige Einschränkung vorhanden ist: Wenn das Steuerelement ein ScrollViewer-Element enthält, kann nicht Transformationen definiert werden, die das Element außerhalb des Feldes. Die ScrollViewer erzwingt einen erheblichen Ausschneidebereich, der einfach transgressed nicht möglich, (soweit ich feststellen wurde, haben). Dies bedeutet, dass Techniken wie ich im letzten Monat Spalte demonstriert noch gültig und in Silverlight 4 wichtig.

Aber die Verwendung von VSM zum Implementieren dieses Pneumatik / UI-Feature in Silverlight 4 ist ein guter Hinweis darauf, dass VSM wahrscheinlich eine zunehmend wichtige Rolle in Zukunft zum Verknüpfen von Code und XAML wiedergegeben wird. Es wird Zeit, die es Anwendungsentwicklern gestartet unter Berücksichtigung der eigenen visuellen Zustände für benutzerdefiniertes Verhalten implementieren.

Charles Petzold redaktionelle langjähriger an MSDN Magazine *.*Er ist derzeit “ Programming Windows Telefon 7 Reihe ” schreiben, die im Herbst 2010 als ein kostenlos herunterladbares e-Book veröffentlicht werden. Preview-Edition steht derzeit über seine Website charlespetzold.com-.