Datenbindung mit XAML
Inhaltsverzeichnis reduzieren
Inhaltsverzeichnis erweitern

Übersicht „Datenbindung“ (XAML)

[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation]

Die Datenbindung ist für Windows-Runtime-Apps mit C++, C# oder Visual Basic eine einfache Möglichkeit, um Daten anzuzeigen und damit zu interagieren. Die Art der Datenanzeige wird dabei von der Datenverwaltung getrennt. Eine Verbindung – oder Bindung – zwischen der Benutzeroberfläche und dem Datenobjekt ermöglicht den Datenfluss zwischen den beiden. Wenn eine Bindung festgelegt wird und Daten geändert werden, können die UI-Elemente, die an die Daten gebunden sind, die Änderung automatisch anzeigen. Entsprechend können vom Benutzer an einem UI-Element vorgenommene Änderungen im Datenobjekt gespeichert werden. Wenn der Benutzer beispielsweise den Wert in einer TextBox ändert, wird der zugrunde liegende Datenwert automatisch aktualisiert, sodass diese Änderung dargestellt wird.

Einige häufige Bindungsszenarien beinhalten das Binden eines ListBox an eine Liste mit Schlagzeilen oder ein Image an das Foto des aktuellen Benutzers.

In diesem Thema werden die Bindungsfeatures ausführlich beschrieben. Eine kurze Einführung in die Konzepte finden Sie unter Schnellstart: Datenbindung an Steuerelemente.

Codebeispiele: In diesem Thema werden einfache Codebeispiele und Auszüge aus Mustern verwendet, um einfache Datenbindungskonzepte darzustellen. Vollständige Beispiele finden Sie unter:

Ein detailliertes Beispiel, in dem die Datenbindung umfassend verwendet wird, finden Sie unter Reversi-Beispiel-App. Weitere Informationen finden Sie unter Reversi, ein Windows Store-Spiel in XAML, C# und C++ und im Abschnitt zur Datenbindung unter Verwenden von Windows Store-App-Features im Reversi-Beispiel.

Zusätzliche C++-Beispiele finden Sie unter Erstellen einer App mit C++.

Roadmap: Wie hängt dieses Thema mit anderen zusammen? Informationen finden Sie unter:

Binden von UI-Elementen an Daten

Jede Bindung enthält Folgendes:

  • Eine Bindungsquelle. Dies ist ein Objekt mit den Daten, die gerendert werden sollen.
  • Ein Bindungsziel. Dies ist eine DependencyProperty eines FrameworkElements zum Rendern der Daten.
  • Ein Binding-Objekt, das die Daten zwischen der Quelle und dem Ziel verschiebt und sie mithilfe eines optionalen Wertkonverters neu formatieren kann.

Folgendes kommt als Datenquelle in Betracht:

  • Jedes CLR-Objekt (Common Language Runtime), einschließlich des Zielelements selbst oder anderer UI-Elemente. Wenn das Ziel eine Datenvorlage ist, kann die Quelle ein UI-Element sein, auf das die Vorlage angewendet wird. Klassen, die Sie in C# und Visual Basic definieren, erzeugen CLR-Objekte, sodass sie standardmäßig auch bindbar sind.
  • Jedes Windows-Runtime-Objekt von einem Typ, der ein BindableAttribute besitzt oder ICustomPropertyProvider implementiert. Klassen, Sie Sie in C++ definieren, erzeugen Windows-Runtime-Objekte, sodass sie standardmäßig auch bindbar sind.

Das Ziel kann eine DependencyProperty eines FrameworkElement sein.

Das Bindungsmodul ruft aus dem Binding-Objekt Informationen zu Folgendem ab:

  • Den Quell- und Zielobjekten.
  • Der Richtung des Datenflusses. Sie geben die Richtung an, indem Sie die Binding.Mode-Eigenschaft festlegen.
  • Dem Wertkonverter, falls einer vorhanden ist. Sie geben einen Wertkonverter an, indem Sie die Converter-Eigenschaft auf eine Instanz einer Klasse festlegen, die IValueConverter implementiert.
  • Andere Einstellungen, z. B. FallbackValue und TargetNullValue. Eine vollständige Liste der Eigenschaften finden Sie unter der Binding-Klasse.

Beispielweise kann die Foreground-Eigenschaft eines TextBox an SolidColorBrush gebunden werden, damit die Farbe des Texts basierend auf den Daten geändert wird. In diesem Szenario ist die Foreground-Eigenschaft das Ziel und das SolidColorBrush-Objekt die Quelle für die Bindung.

Im folgenden Beispiel ist dargestellt, wie die Foreground-Farbe eines TextBox-Elements an SolidColorBrush gebunden wird. Die Bindungsquelle ist eine Eigenschaft der MyColors-Klasse, die später in diesem Thema beschrieben wird.



<TextBox x:Name="MyTextBox" Text="Text" Foreground="{Binding Brush1}"/>




// Create an instance of the MyColors class 
// that implements INotifyPropertyChanged.
MyColors textcolor = new MyColors();

// Brush1 is set to be a SolidColorBrush with the value Red.
textcolor.Brush1 = new SolidColorBrush(Colors.Red);

// Set the DataContext of the TextBox MyTextBox.
MyTextBox.DataContext = textcolor;


Hinweis  In diesem Beispiel wird eine XAML-Attributsyntax verwendet, um die Bindung zu erstellen. Sie können auch die Objektelementsyntax verwenden, um die Bindung in XAML zu erstellen. Weitere Informationen finden Sie in der XAML-Übersicht.
 

Die Bindung wird in XAML mithilfe der {Binding ...}-Syntax erstellt. Die Quelle wird im Code durch Festlegen der DataContext-Eigenschaft für die TextBox festgelegt.

Der Datenkontext wird vererbt. Wenn Sie den Datenkontext für ein übergeordnetes Element festlegen, wird für die untergeordneten Elemente derselbe Datenkontext verwendet. Ein untergeordnetes Element kann dieses Verhalten außer Kraft setzen, indem es die Source-Eigenschaft für sein Bindungsobjekt oder seinen DataContext festlegt. Diese Außerkraftsetzung wird dann auf die dem untergeordneten Element untergeordneten Elemente angewendet.

Das Festlegen des Datenkontexts ist hilfreich, wenn Sie mehrere Bindungen haben möchten, die dieselbe Quelle verwenden. Wenn Sie die Quelle für eine einzelne Bindung festlegen möchten, legen Sie die Source-Eigenschaft für das Binding-Objekt fest.

Sie können auch die ElementName-Eigenschaft oder die RelativeSource-Eigenschaft verwenden, um die Bindungsquelle anzugeben. Die ElementName-Eigenschaft ist hilfreich, wenn Sie eine Bindung an andere Elemente in Ihrer App vornehmen – beispielsweise wenn Sie einen Schieberegler verwenden, um die Breite einer Schaltfläche anzupassen. Die RelativeSource-Eigenschaft ist hilfreich, wenn die Bindung in einer ControlTemplate angegeben ist. Weitere Informationen finden Sie unter Bindungsmarkuperweiterung und RelativeSource-Markuperweiterung.

Sie können eine Bindung an eine Eigenschaft des Quellobjekts vornehmen, indem Sie die Binding.Path-Eigenschaft festlegen. Die Path-Eigenschaft unterstützt eine Vielzahl von Syntaxoptionen zum Binden geschachtelter Eigenschaften, angefügter Eigenschaften sowie von Ganzzahl- und Zeichenfolgenindexern. Weitere Informationen finden Sie unter Property-path-Syntax. Die Bindung an Zeichenfolgenindexer hat dieselbe Wirkung wie die Bindung an dynamische Eigenschaften, ohne ICustomPropertyProvider implementieren zu müssen.

Wenn Sie ein Textsteuerelement an einen Wert binden, bei dem es sich nicht um eine Zeichenfolge handelt, wird der Wert vom Datenbindungsmodul in eine Zeichenfolge konvertiert. Wenn der Wert ein Verweistyp ist, ruft das Datenbindungsmodul den Zeichenfolgenwert ab, indem ICustomPropertyProvider.GetStringRepresentation oder IStringable.ToString abgerufen wird (falls verfügbar). Andernfalls wird Object.ToString aufgerufen. Beachten Sie jedoch, dass das Bindungsmodul alle ToString-Implementierungen ignoriert, bei denen die Basisklassenimplementierung ausgeblendet wird. Stattdessen sollte bei Implementierungen von Unterklassen die ToString-Basisklassenmethode überschrieben werden. In nicht verwalteten Sprachen wird analog dazu scheinbar ICustomPropertyProvider und IStringable implementiert. Alle Aufrufe von GetStringRepresentation und IStringable.ToString werden jedoch an Object.ToString oder eine Überschreibung dieser Methode weitergeleitet, und niemals an eine neue ToString-Implementierung, bei der die Basisklassenimplementierung ausgeblendet wird.

Insgesamt wird im vorherigen Beispiel durch das Bindungsmodul eine Bindung erstellt, bei der es sich standardmäßig um eine unidirektionale Bindung handelt. Sie verbindet die Foreground-Eigenschaft des TextBox mit der Brush1-Eigenschaft des textcolor-Objekts.

Erstellen von Bindungen im Code

Sie können UI-Elemente auch mit Daten verbinden, indem Sie anstelle von XAML prozeduralen Code verwenden. Erstellen Sie dazu ein neues Binding-Objekt, legen Sie die entsprechenden Eigenschaften fest, und rufen Sie dann FrameworkElement.SetBinding oder BindingOperations.SetBinding auf. Die programmgesteuerte Erstellung von Bindungen ist nützlich, wenn Sie die Bindungseigenschaftswerte zur Laufzeit auswählen oder eine einzelne Bindung für mehrere Steuerelemente gemeinsam verwenden möchten. Beachten Sie jedoch, dass Sie die Bindungseigenschaftswerte nach dem Aufrufen von SetBinding nicht ändern können.

Im folgenden Beispiel wird veranschaulicht, wie Sie die vorherige Bindung im Code implementieren.



<TextBox x:Name="MyTextBox" Text="Text"/>




// Create an instance of the MyColors class 
// that implements INotifyPropertyChanged.
MyColors textcolor = new MyColors();

// Brush1 is set to be a SolidColorBrush with the value Red.
textcolor.Brush1 = new SolidColorBrush(Colors.Red);

// Set the DataContext of the TextBox MyTextBox.
MyTextBox.DataContext = textcolor;

// Create the binding and associate it with the text box.
Binding binding = new Binding() { Path = new PropertyPath("Brush1") };
MyTextBox.SetBinding(TextBox.ForegroundProperty, binding);


Richtung des Datenflusses

Die Mode-Eigenschaft jeder Bindung bestimmt, wie und wann die Daten fließen. Windows-Runtime-Apps mit C++, C# oder Visual Basic können drei Arten von Bindungen verwenden:

  • OneTime-Bindungen aktualisieren das Ziel mit den Quelldaten, wenn die Bindung erstellt wird.
  • OneWay-Bindungen aktualisieren das Ziel mit den Quelldaten, wenn die Bindung erstellt wird, und immer dann, wenn sich die Daten ändern. Dies ist der Standardmodus.
  • TwoWay-Bindungen aktualisieren das Ziel und die Quelle, wenn sich eines der beiden ändert. Eine Ausnahme bei diesem Verhalten besteht darin, dass Änderungen am TextBox.Text nicht nach jedem Tastaturanschlag des Benutzers an eine gebundene Quelle gesendet werden, es sei denn, Binding.UpdateSourceTrigger ist auf PropertyChanged festgelegt. Die Änderungen werden standardmäßig erst gesendet, wenn die TextBox den Fokus verliert.

Sie können das Verhalten von TwoWay-Bindungen ändern, damit Werte nicht automatisch auf die Quelle kopiert werden, sondern nur zu den von Ihnen gewünschten Zeitpunkten. Legen Sie dazu die Binding.UpdateSourceTrigger-Eigenschaft auf Explicit fest. Sie können dann GetBindingExpression auf dem Ziel aufrufen, um ein BindingExpression-Objekt zu erhalten, und anschließend BindingExpression.UpdateSource aufrufen, um die Datenquelle programmgesteuert zu aktualisieren.

Änderungsbenachrichtigung

Damit Änderungen am Quellobjekt an das Ziel weitergegeben werden, muss die Quelle die INotifyPropertyChanged-Schnittstelle implementieren. INotifyPropertyChanged hat das PropertyChanged-Ereignis. Dieses Ereignis teilt dem Bindungsmodul die Änderung der Quelle mit, damit das Bindungsmodul den Zielwert aktualisieren kann. Für C# oder Microsoft Visual Basic implementieren Sie System.ComponentModel.INotifyPropertyChanged. Für Visual C++-Komponentenerweiterungen (C++/CX) implementieren Sie Windows::UI::Xaml::Data::INotifyPropertyChanged.

In diesem Beispiel implementiert die MyColors-Klasse die INotifyPropertyChanged-Schnittstelle für die OneWay-Bindung.



// Create a class that implements INotifyPropertyChanged.
public class MyColors : INotifyPropertyChanged
{
    private SolidColorBrush _Brush1;

    // Declare the PropertyChanged event.
    public event PropertyChangedEventHandler PropertyChanged;

    // Create the property that will be the source of the binding.
    public SolidColorBrush Brush1
    {
        get { return _Brush1; }
        set
        {
            _Brush1 = value;
            // Call NotifyPropertyChanged when the source property 
            // is updated.
            NotifyPropertyChanged("Brush1");
        }
    }

    // NotifyPropertyChanged will fire the PropertyChanged event, 
    // passing the source property that is being updated.
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, 
                new PropertyChangedEventArgs(propertyName));
        }
    }
}


Sie können das PropertyChanged-Ereignis auslösen, um anzuzeigen, dass sich alle Nicht-Indexereigenschaften für das Objekt geändert haben, indem Sie für PropertyChangedEventArgs.PropertyName den Wert String.Empty verwenden. Beachten Sie, dass Sie null (Nothing in Visual Basic) – anders als in Windows Presentation Foundation (WPF) und Microsoft Silverlight – nicht dafür verwenden können.

Hinweis  Für C# oder Microsoft Visual Basic verwenden Sie System.ComponentModel.PropertyChangedEventArgs. Für C++/CX verwenden Sie Windows::UI::Xaml::Data::PropertyChangedEventArgs.
 

Sie können Änderungsbenachrichtigungen auch für Indexereigenschaften verwenden. Sie können das PropertyChanged-Ereignis auslösen, um anzugeben, dass die Indexereigenschaften für das Objekt geändert wurden, indem Sie den PropertyChangedEventArgs.PropertyName-Wert "Item[indexer]" für bestimmte Indexer (wobei indexer der Indexwert ist) oder "Item[]" für alle Indexer verwenden.

Binden an Sammlungen

Ein Bindungsquellobjekt kann wie ein einzelnes Objekt, dessen Eigenschaften Daten enthalten, oder wie eine Sammlung von Objekten behandelt werden. Beispielweise möchten Sie eine Liste mit Elementen wie monatlichen Kreditkartenabrechnungen anzeigen. Verwenden Sie dazu ItemsControl und DataTemplate, um jedes Element in einer Sammlung anzuzeigen.



<Grid.Resources>

  <DataTemplate x:Name="dataTemplate">
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <TextBlock Grid.Column="0" 
        Text="{Binding Month, Converter={StaticResource Converter1}}"/>
      <TextBlock Grid.Column="1" Text="{Binding Total}"/>    
    </Grid>
  </DataTemplate>

</Grid.Resources>

<ItemsControl x:Name="IC1" ItemsSource="{Binding}" 
  ItemTemplate="{StaticResource dataTemplate}"/>


In C#- und Visual Basic-Code können Sie List(Of T) auffüllen und binden, um eine sich nicht ändernde Auflistung anzuzeigen. Wenn Elemente der Auflistung zur Laufzeit hinzugefügt oder aus ihr entfernt werden und Sie möchten, dass das Ziel in diesem Fall mit der ItemsSource aktualisiert wird, verwenden Sie stattdessen ObservableCollection(Of T). In C++-Code können Sie Vector<T>-Instanzen für sich ändernde und sich nicht ändernde Sammlungen auffüllen und binden. Wenn Sie eine Bindung an Ihre eigenen Sammlungsklassen vornehmen möchten, verwenden Sie die Anleitung in der folgenden Tabelle.

Das Datenbindungssystem unterstützt die folgenden Bindungsszenarien.

Inkrementelles Laden von Daten

Sie können mithilfe von inkrementellem Laden Listensteuerelemente an beliebig große Datenquellen binden und dennoch eine hohe Leistung erreichen. Zum Beispiel können Sie Listensteuerelemente an Ergebnisse von Bildabfragen in Bing binden, ohne alle Ergebnisse auf einmal laden zu müssen. Stattdessen laden Sie nur einige der Ergebnisse sofort und weitere Ergebnisse nach Bedarf. Sie müssen ISupportIncrementalLoading für eine Datenquelle umsetzen, die die Sammlungsänderungsbenachrichtigung unterstützt, um das inkrementelle Laden zu unterstützen. Wenn das Datenbindungsmodul weitere Daten anfordert, muss Ihre Datenquelle die passenden Anforderungen senden, die Ergebnisse integrieren und dann die passende Benachrichtigung senden, um die UI zu aktualisieren. Weitere Infos finden Sie im XAML-Datenbindungsbeispiel.

Bindung an Ordner und Dateilisten

Hinweis  

Nur Windows Store-Apps. Sie können die APIs im Windows.Storage-Namespace verwenden, um Ordner- und Dateidaten abzurufen. Die verschiedenen GetFilesAsync-, GetFoldersAsync- und GetItemsAsync-Methoden geben jedoch keine Werte zurück, die zur Bindung an Listensteuerelemente geeignet sind. Stattdessen müssen Sie die Bindung an die Rückgabewerte der GetVirtualizedFilesVector-, GetVirtualizedFoldersVector-, und GetVirtualizedItemsVector-Methoden der FileInformationFactory-Klasse vornehmen. Das folgende Codebeispiel aus dem Beispiel für StorageDataSource und GetVirtualizedFilesVector veranschaulicht das typische Verwendungsmuster.


protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var library = Windows.Storage.KnownFolders.PicturesLibrary;
    var queryOptions = new Windows.Storage.Search.QueryOptions();
    queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
    queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;

    var fileQuery = library.CreateFileQueryWithOptions(queryOptions);

    var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
        fileQuery,
        Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
        190,
        Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
        false
        );

    var dataSource = fif.GetVirtualizedFilesVector();
    PicturesGrid.ItemsSource = dataSource;
}


Hinweis  

Nur Windows Store-Apps. Üblicherweise verwenden Sie diesen Ansatz, um eine schreibgeschützte Ansicht der Datei- und Ordnerinformationen zu erstellen. Sie können Zwei-Wege-Bindungen an die Datei- und Ordnereigenschaften erstellen, zum Beispiel um Benutzern die Bewertung eines Titels in einer Musikansicht zu ermöglichen. Änderungen werden jedoch nicht beibehalten, bis Sie die passende SavePropertiesAsync-Methode (z. B. MusicProperties.SavePropertiesAsync) aufrufen. Sie müssen für Änderungen einen Commit ausführen, wenn das Element den Fokus verliert, da dadurch das Rücksetzen der Auswahl ausgelöst wird.

Beachten Sie, dass eine Zwei-Wege-Bindung mit dieser Technik nur für indizierte Orte wie "Musik" funktioniert. Sie können durch Aufrufen der FolderInformation.GetIndexedStateAsync-Methode feststellen, ob ein Ort indiziert ist.

Darüber hinaus kann der Wert null von einem virtualisierten Vektor für einige Elemente vor dem Füllen des Werts zurückgegeben werden. Beispielsweise sollten Sie nach null suchen, bevor Sie den SelectedItem-Wert eines Listensteuerelements verwenden, das an einen virtualisierten Vektor gebunden ist. Stattdessen können Sie jedoch auch SelectedIndex verwenden.

Gruppieren von Daten und Nachverfolgen des aktuellen Elements

Sie können auch Bindungen an Instanzen der CollectionViewSource-Klasse vornehmen, um Auflistungen von Auflistungen anzuzeigen und das aktuelle Element in mehreren Ansichten nachzuverfolgen. In der Regel definieren Sie eine CollectionViewSource als XAML-Ressource und binden sie mithilfe der StaticResource-Markuperweiterung daran. Sie können dann die Source-Eigenschaft im CodeBehind auf einen unterstützten Auflistungstyp festlegen.

Alle Steuerelemente, die Sie an dieselbe CollectionViewSource binden, verfügen immer über dasselbe aktuelle Element. Und alle Bindungen mit Path-Einstellungen werden automatisch an Eigenschaften des aktuellen Elements gebunden. Sie können programmgesteuert über die ICollectionView.CurrentItem-Eigenschaft des CollectionViewSource.View-Eigenschaftswerts auf das aktuelle Element zugreifen.

Wenn die Elemente in der Sammlung selbst Sammlungen sind oder wenn sie Objekte mit Sammlungen sind, können Sie die Sammlungen als Gruppen innerhalb der größeren Sammlung anzeigen. Legen Sie dazu die IsSourceGrouped-Eigenschaft auf true fest. Wenn die Elemente Auflistungen enthalten, aber selbst keine Auflistungen sind, müssen Sie die ItemsPath-Eigenschaft auch auf den Namen der Auflistungseigenschaft festlegen. Wenn Sie zum Beispiel an eine CustomerList-Auflistung von Customer-Objekten anbinden und die Customer-Klasse über eine Orders-Eigenschaft verfügt, die eine Auflistung von Order-Objekten darstellt, können Sie mithilfe der folgenden XAML Bestellungen nach Kunden gruppieren.


<local:CustomerList x:Key="CustomerData"/>
<CollectionViewSource x:Name="Customers"
  Source="{StaticResource CustomerData}"
  IsSourceGrouped="True" ItemsPath="Orders"/>


Sie können dann eine Gruppenkopfvorlage, die an Eigenschaften der Customer-Klasse gebunden ist, sowie eine Elementvorlage, die an Eigenschaften der Order-Klasse gebunden ist, erstellen. Sie können auch programmgesteuert über die CollectionViewSource.CollectionGroups-Eigenschaft auf die Gruppen zugreifen.

Im folgenden Codebeispiel ist das Binden eines ListBox-Steuerelements an die Ergebnisse einer LINQ-Gruppierungsabfrage dargestellt. In diesem Beispiel wird eine Sammlung aus Teams nach Ort gruppiert und mit dem Ortsnamen in den Gruppenheadern angezeigt. Dies wird durch den "Key"-Eigenschaftspfad in Referenz zum Key-Wert der Gruppe angezeigt. Die vollständige Codeauflistung finden Sie im Beispiel zur Datenbindung. Ähnlichen Beispielcode zum Gruppieren finden Sie im Beispiel zur gruppierten GridView.


<Grid>

  <Grid.Resources>
    <CollectionViewSource x:Name="groupInfoCVS" IsSourceGrouped="true"/>
  </Grid.Resources>

  <ListBox x:Name="lbGroupInfoCVS" 
    ItemsSource="{Binding Source={StaticResource groupInfoCVS}}">

    <ListBox.GroupStyle>
      <GroupStyle>
        <GroupStyle.HeaderTemplate>
          <DataTemplate>

            <TextBlock Text="{Binding Key}" />

          </DataTemplate>
        </GroupStyle.HeaderTemplate>
      </GroupStyle>
    </ListBox.GroupStyle>

    <ListBox.ItemTemplate>
      <DataTemplate>

        <Border Background="{Binding Color}" 
          Width="200" CornerRadius="10" HorizontalAlignment="Left">

          <TextBlock Text="{Binding Name}" 
            Style="{StaticResource DescriptionTextStyle}" 
            HorizontalAlignment="Center" FontWeight="Bold"/>

        </Border>
      </DataTemplate>
    </ListBox.ItemTemplate>

  </ListBox>

</Grid>



Teams teams = new Teams();
var result = 
    from t in teams 
    group t by t.City into g 
    orderby g.Key 
    select g;
groupInfoCVS.Source = result;


Eine weitere Option bei der Bindung an mehrstufige Daten wie Kategorien mit Unterkategorien ist die Anzeige der Stufen als eine Reihe von Listen. Eine Auswahl in einer Liste hat dabei Einfluss auf den Inhalt der nachfolgenden Listen. Die Listen können synchron gehalten werden, indem jede Liste jeweils an ihre eigene CollectionViewSource und die CollectionViewSource-Instanzen in einer Kette gebunden werden. Weitere Informationen finden Sie unter So wird's gemacht: Binden an hierarchische Daten und Erstellen einer Master/Details-Ansicht.

Datenkonvertierungen

Unter Umständen müssen Sie Daten in einem Format anzeigen, dass sich vom Speicherformat unterscheidet. Es folgen einige Beispiele:

  • Speichern einer Farbe als RGBA-Wert, aber Anzeigen als Zeichenfolgenname.
  • Speichern einer Zahl als Gleitkommawert, aber Anzeigen als Währungswert.
  • Speichern eines Datums als DateTime, aber Anzeigen in einem Kalender.
  • Speichern eines null-Werts, aber Anzeigen als standardmäßiger Anzeigename.

Ab Windows 8.1 können Sie einen standardmäßigen Anzeigenamen für null-Sicherungswerte anzeigen, indem Sie die TargetNullValue-Eigenschaft festlegen.

Sie können für jede Bindung einen Konverter festlegen. Erstellen Sie eine Klasse und implementieren Sie die IValueConverter-Schnittstelle, um den Konverter für jedes Szenario anzupassen. Im folgenden Beispiel ist die Implementierung von IValueConverter dargestellt.



// Custom class implements the IValueConverter interface.
public class DateToStringConverter : IValueConverter
{

    #region IValueConverter Members

    // Define the Convert method to change a DateTime object to 
    // a month string.
    public object Convert(object value, Type targetType, 
        object parameter, string language)
    {
        // value is the data from the source object.
        DateTime thisdate = (DateTime)value;
        int monthnum = thisdate.Month;
        string month;
        switch (monthnum)
        {
            case 1:
                month = "January";
                break;
            case 2:
                month = "February";
                break;
            default:
                month = "Month not found";
                break;
        }
        // Return the value to pass to the target.
        return month;

    }

    // ConvertBack is not implemented for a OneWay binding.
    public object ConvertBack(object value, Type targetType, 
        object parameter, string language)
    {
        throw new NotImplementedException();
    }

    #endregion
}


Das Bindungsmodul ruft die Methoden Convert und ConvertBack auf, wenn der Converter-Parameter für die Bindung definiert ist. Wenn Daten aus der Quelle übergeben werden, ruft das Bindungsmodul Convert auf und übergibt die zurückgegebenen Daten an das Ziel. Wenn Daten aus dem Ziel übergeben werden, ruft das Bindungsmodul ConvertBack auf und übergibt die zurückgegebenen Daten an die Quelle. Im folgenden Beispiel ist die Festlegung des Converter-Parameters dargestellt.



<UserControl.Resources>
  <local:DateToStringConverter x:Key="Converter1"/>
</UserControl.Resources>

...

<TextBlock Grid.Column="0" 
  Text="{Binding Month, Converter={StaticResource Converter1}}"/>


Der Konverter verfügt auch über optionale Parameter: ConverterLanguage ermöglicht das Angeben der für die Konvertierung zu verwendenden Sprache und ConverterParameter ermöglicht das Übergeben eines Parameters für die Konvertierungslogik. Ein Beispiel, in dem ein Konverterparameter verwendet wird, finden Sie unter IValueConverter.

Wenn bei der Konvertierung ein Fehler auftritt, lösen Sie keine Ausnahme aus. Geben Sie stattdessen DependencyProperty.UnsetValue zurück, wodurch die Datenübertragung beendet wird.

Zum Anzeigen eines Standardwerts, der jeweils eingeblendet wird, wenn die Bindungsquelle nicht aufgelöst werden kann, legen Sie die FallbackValue-Eigenschaft fest. Dies ist hilfreich bei der Behandlung von Konvertierungs- und Formatierungsfehlern. Außerdem ist es nützlich zum Binden an Quelleigenschaften, die in einer gebundenen Sammlung ggf. nicht für alle Objekte vorhanden sind.

Debuggen von Datenbindungen

Sie können Datenbindungen in Microsoft Visual Studio debuggen. Wenn Sie Ihre App mit dem angefügten Debugger ausführen, werden alle Bindungsfehler in Visual Studio im Fenster Ausgabe angezeigt. Dies ist beispielsweise hilfreich, wenn Sie Eigenschaften in Ihren Datenklassen ändern, aber vergessen, Ihre XAML-Bindungsausdrücke zu aktualisieren.

Anzeigen von Daten im Designer

Wenn Sie den Designer verwenden, um eine datengebundene UI zu erstellen, können Sie Stichprobendaten anzeigen, um Layoutgrößen genau anzusehen und realistische Ergebnisse für die automatische Größenanpassung zu sehen.

Sie müssen Daten in XAML deklarieren, anstatt lediglich die DataContext-Eigenschaft im CodeBehind programmgesteuert einzustellen, um Daten im Designer anzuzeigen. Dies ist erforderlich, da beim Öffnen einer Seite oder eines Benutzersteuerelements im Designer keine Instanziierung erfolgt. Das zugehörige XAML wird zwar vom Designer analysiert. Das CodeBehind wird jedoch nicht ausgeführt. (Alle untergeordneten Benutzersteuerelement, die vom Designer beim Analysieren des XAML-Inhalts gefunden werden, werden allerdings instanziiert.)

Abhängig davon, ob Sie während der Laufzeit und der Designzeit die gleichen Daten anzeigen möchten, können Sie Daten in XAML mithilfe verschiedener Techniken definieren.

Anzeigen der gleichen Daten während der Designzeit und der Laufzeit

Wenn Ihre App nur lokale Daten verwendet oder wenn Sie einen Prototypen für Ihre App erstellen, ist die Anzeige von echten Daten während der Designzeit nützlich. Sie können zum Beispiel ein Datenobjekt zu einer Ressource deklarieren und dann von anderen Elementen auf diese verweisen, so wie es der folgende Code aus So wird's gemacht: Binden an hierarchische Daten und Erstellen einer Master/Details-Ansicht zeigt:



<local:LeagueList x:Key="LeagueData"/>
<CollectionViewSource x:Name="Leagues"
    Source="{StaticResource LeagueData}"/>


In diesen Fall instanziiert der XAML-Parser die LeagueList-Sammlungsklasse sowohl während der Designzeit als auch während der Laufzeit und der LeagueList-Konstruktur füllt sich selbst mit Beispieldaten.

Anzeigen unterschiedlicher Daten während der Designzeit und der Laufzeit

Wenn Sie während der Designzeit Beispieldaten und während der Laufzeit echte Daten anzeigen möchten, stehen Ihnen einige Optionen zur Verfügung. Die einfachste Option ist, Ihre Daten wie zuvor veranschaulicht in XAML zu deklarieren und Code in Ihre Datenklasse einzufügen, um zu erkennen, ob dieser während der Designzeit oder während der Laufzeit aufgerufen wird. Sie können zum Beispiel GetSampleData- und GetRealData-Methoden in der Datenklasse festlegen und dann folgenden Code in deren Konstruktor verwenden.


if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
{
    GetSampleData();
}
else GetRealData();


Verwenden von Designzeit-Attributen

Eine weitere Option zur Anzeige von Beispieldaten während der Designzeit ist die Deklaration dieser Beispieldaten in XAML mithilfe verschiedener Datenattribute aus dem XML-Namespace des Designers. Dieser XML-Namespace wird üblicherweise wie folgt mit einem d:-Präfix deklariert:


xmlns:d="http://schemas.microsoft.com/expression/blend/2008"


Mit dieser Deklaration werden Attribute mit d:-Präfixen nur während der Designzeit interpretiert und während der Laufzeit ignoriert. In der folgenden XAML wird zum Beispiel das d:Source-Attribut nur für Beispieldaten zur Designzeit verwendet, während das Source-Attribut nur für echte Daten während der Laufzeit verwendet wird.


<CollectionViewSource
  x:Name="groupedItemsViewSource"
  Source="{Binding Groups}"
  IsSourceGrouped="true"
  ItemsPath="Items"
  d:Source="{Binding ItemGroups, 
    Source={d:DesignInstance Type=data:SampleDataSource, 
      IsDesignTimeCreatable=True}}"/>


Dieser Code stammt aus den Projektvorlagen Grid Application und Split Application, die Sie auf Einzelheiten zur Beispieldatenquelle und zum prozeduralen Code, der zum Festlegen der Laufzeitdatenquelle verwendet wird, untersuchen können. Die d:Source-Eigenschaft gilt lediglich für die CollectionViewSource-Klasse, für andere Klassen können Sie jedoch d:DataContext auf die gleiche Weise wie DataContext verwenden.

Die d:DesignInstance-Markuperweiterung gibt an, dass die Designzeitquelle eine Designer-erstellte Instanz auf Basis des SampleDataSource-Typs ist (wie durch die Type-Einstellung angegeben). Die IsDesignTimeCreatable-Einstellung gibt an, dass der Designer den Typ direkt instanziiert, was zur Anzeige der durch den Typ-Konstruktor erzeugten Beispieldaten notwendig ist. Wenn Sie dieses Attribut nicht (oder auf False) festlegen, generiert und instanziiert der Designer stattdessen eine Lightweight-Klasse mit denselben bindbaren Eigenschaften. Dies ist nützlich, wenn Sie möchten, dass die Eigenschaften als potenziell bindbare Ziele im Datenbindungs-Designer erscheinen, Ihnen die Anzeige der Beispieldaten jedoch nicht wichtig ist.

Verwenden dateibasierter Beispieldaten

Eine Alternative zu d:DesignInstance ist die d:DesignData-Markuperweiterung. Diese ermöglicht Ihnen das Verwenden von in XAML- oder JSON-Dateien definierten Beispieldaten anstelle von programmatisch in Ihren Datenklassen erstellten Daten. Sie können auch auf Beispieldaten verweisen, indem Sie Markup wie den folgenden verwenden:


<Grid d:DataContext="{Binding Source={d:DesignData Source=/Data/SampleData.xaml}}">
  <TextBlock FontSize="50" Text="{Binding Name}"/>
</Grid>


In diesem Fall enthält die SampleData.xaml-Datei Markup wie den folgenden:


<Customer xmlns="using:DemoProject.Data" Name="Customer One"/>


Die xmlns-Deklaration zeigt an, dass der Markup auf eine Klasse im DemoProject.Data-Projekt verweist. Wenn Sie keine XAML-Dateien, sondern JSON-Datendateien verwenden, müssen Sie dem d:DesignData-Markup eine Type-Einstellung hinzufügen:


<Grid 
  xmlns:data="using:DemoProject.Data"
  d:DataContext="{Binding Source={d:DesignData 
    Source=/Data/SampleData.json, Type=data:SampleDataSource}}">
  <TextBlock FontSize="50" Text="{Binding Name}"/>
</Grid>


Verwandte Themen

Roadmaps
Roadmap für Windows-Runtime-Apps mit C# oder Visual Basic
Roadmap für Windows-Runtime-Apps mit C++
Beispiele
XAML-Datenbindungsbeispiel
Beispiel für XAML-GridView-Gruppierung und SemanticZoom
Beispiel für StorageDataSource und GetVirtualizedFilesVector
Reversi-Beispiel-App
Szenarien für Reversi-Beispielfeatures: Datenbindung
Referenz
Binding
DataContext
DependencyProperty
CollectionViewSource
ObservableCollection(Of T)
DataTemplate
ControlTemplate
INotifyPropertyChanged
INotifyCollectionChanged
IValueConverter
ICustomPropertyProvider
ISupportIncrementalLoading
Konzepte
Schnellstart: Datenbindung an Steuerelemente
So wird's gemacht: Binden an hierarchische Daten und Erstellen einer Master/Details-Ansicht
Designzeitattribute
Übersicht über XAML
Bindungsmarkuperweiterung
Property-path-Syntax
RelativeSource-Markuperweiterung
Übersicht über Abhängigkeitseigenschaften
Benutzerdefinierte Abhängigkeitseigenschaften
Übersicht über angefügte Eigenschaften
ResourceDictionary- und XAML-Ressourcenreferenzen

 

 

Anzeigen:
© 2017 Microsoft