Navigieren mit CollectionViewSource

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Bisher haben wir oft mit Detailansichten von Datensätzen wie beispielsweise für Kunden oder Produkten gearbeitet, die zum Anlegen oder Bearbeiten eines einzelnen Datensatzes geeignet waren. Von Access kennen Sie die Möglichkeit, mit den Navigationsschaltflächen auch in solchen Detailformularen zu navigieren und von einem zum anderen Datensatz zu wechseln, ohne zwischendurch zu einem Übersichtsformular zu wechseln. In diesem Artikel wollen wir zeigen, wie Sie das unter WPF so abbilden können, wie es auch unter Access möglich ist. Dabei nutzen wir die Möglichkeiten der CollectionViewSource.

Ziel des Artikels

In diesem Artikel wollen wir einer Seite, die eine Detailansicht eines Datensatzes – hier eines Kunden – anzeigt, Navigationsschaltflächen wie von den Formularen von Access bekannt hinzufügen. Die WPF-Seite besteht dabei grob aus einem Grid-Element, das wiederum zwei weitere Grid-Element aufnimmt. Es definiert außerdem im Element Window.Resources ein CollectionViewSource-Element, das wir im Code behind mit den anzuzeigenden Daten füllen:

<Window x:Class="MainWindow" ... Title="MainWindow" Height="450" Width="800">
     <Window.Resources>
         ...
         <CollectionViewSource x:Key="kundeViewSource"></CollectionViewSource>
     </Window.Resources>

Danach folgt die Definition des übergeordneten Grid-Elements:

     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="Auto"></RowDefinition>
             <RowDefinition Height="Auto"></RowDefinition>
             <RowDefinition Height="*"></RowDefinition>
         </Grid.RowDefinitions>

Das erste untergeordnete Grid-Element erhält als DataContext das als statische Ressource hinterlegte CollectionViewSource-Element sowie einige Zeilen für die Anzeige der einzelnen Felder und Spalten zur Aufteilung von Bezeichnungsfeldern und gebundenen Steuerelementen:

         <Grid DataContext="{StaticResource kundeViewSource}">
             <Grid.RowDefinitions>
                 <RowDefinition Height="Auto"></RowDefinition>
                 ...
                 <RowDefinition Height="*"></RowDefinition>
             </Grid.RowDefinitions>
             <Grid.ColumnDefinitions>
                 <ColumnDefinition Width="Auto"></ColumnDefinition>
                 <ColumnDefinition Width="Auto"></ColumnDefinition>
                 <ColumnDefinition Width="*"></ColumnDefinition>
             </Grid.ColumnDefinitions>

Danach folgen die Definitionen für Steuerelemente, die in den einzelnen Zeilen und Spalten angezeigt werden sollen – zum Beispiel für die ID und den Vornamen:

             <Label Content="ID:" Grid.Column="0" />
             <TextBox x:Name="txtID" Grid.Column="1" HorizontalAlignment="Left"                 Text="{Binding ID, Mode=TwoWay}" Width="50" IsEnabled="False" BorderBrush="Transparent" />
             <Label Content="Vorname:" Grid.Column="0" Grid.Row="2" />
             <TextBox x:Name="txtVorname" Grid.Column="1" Grid.Row="2" Width="202" 
                 Text="{Binding Vorname, Mode=TwoWay, ValidatesOnDataErrors=True}" Margin="2,2,0,3" />
             ...
         </Grid>

Das zweite untergeordnete Grid-Element enthält ein StackPanel-Element mit den vier Schaltflächen und dem Textfeld zur Anzeige der Position des Datensatzzeigers beziehungsweise zur Eingabe des anzuzeigenden Datensatzes, das wir im folgenden Abschnitt beschreiben.

Aufbau der Navigationssteuerelemente

Die Navigationsschaltflächen wollen wir genau wie unter Access abbilden. Das heißt, dass wir von links nach rechts die folgenden Steuerelemente hinzufügen wollen:

  • Schaltfläche zum Navigieren zum ersten Datensatz
  • Schaltfläche zum Navigieren zum vorherigen Datensatz
  • Textfeld zur Anzeige der aktuellen Position im Format x von y, wobei y die Gesamtzahl der angezeigten Datensätze enthält. In dieses Textfeld kann der Benutzer die Position eingeben, zu der er navigieren möchte.
  • Schaltfläche zum Navigieren zum nächsten Datensatz
  • Schaltfläche zum Navigieren zum letzten Datensatz

Die Steuerelemente organisieren wir in einem StackPanel-Steuerelement mit horizontaler Ausrichtung, das wir wie folgt definieren:

<StackPanel Orientation="Horizontal" Grid.Row="10" Grid.ColumnSpan="4" >
     <Button x:Name="btnFirst" Click="btnFirst_Click">
         <Image Source="images/media_beginning.png" Width="24" Height="24"></Image>
     </Button>
     <Button x:Name="btnPrevious" Click="btnPrevious_Click">
         <Image Source="images/media_playback.png" Width="24" Height="24"></Image>
     </Button>
     <TextBox x:Name="txtNavigation" MinWidth="50"         Text="{Binding MyCurrentPosition, UpdateSourceTrigger=LostFocus}"         GotFocus="txtNavigation_GotFocus"></TextBox>
     <Button x:Name="btnNext" Click="btnNext_Click">
         <Image Source="images/media_play.png" Width="24" Height="24"></Image>
     </Button>
     <Button x:Name="btnLast" Click="btnLast_Click">
         <Image Source="images/media_end.png" Width="24" Height="24"></Image>
     </Button>
</StackPanel>

Die Bilddateien für die hier definierten Image-Elemente finden sie im Beispielprojekt im Ordner images. Der XAML-Code hierfür sieht wie folgt aus:

<Grid Grid.Row="1">
     <StackPanel Orientation="Horizontal" Grid.Row="10" Grid.ColumnSpan="4" >
         <Button x:Name="btnFirst" Click="btnFirst_Click" IsEnabled="{Binding FirstOrPreviousEnabled}">
             <Image Source="images/media_beginning.png" Width="24" Height="24"></Image>
         </Button>
         <Button x:Name="btnPrevious" Click="btnPrevious_Click"             IsEnabled="{Binding FirstOrPreviousEnabled, UpdateSourceTrigger=PropertyChanged}">
             <Image Source="images/media_playback.png" Width="24" Height="24"></Image>
         </Button>
         <TextBox x:Name="txtNavigation" MinWidth="50"             Text="{Binding MyCurrentPosition, UpdateSourceTrigger=LostFocus}"             GotFocus="txtNavigation_GotFocus" KeyDown="txtNavigation_KeyDown"></TextBox>
         <Button x:Name="btnNext" Click="btnNext_Click"             IsEnabled="{Binding NextOrLastEnabled, UpdateSourceTrigger=PropertyChanged}">
             <Image Source="images/media_play.png" Width="24" Height="24"></Image>
         </Button>
         <Button x:Name="btnLast" Click="btnLast_Click" 
             IsEnabled="{Binding NextOrLastEnabled, UpdateSourceTrigger=PropertyChanged}">
             <Image Source="images/media_end.png" Width="24" Height="24"></Image>
         </Button>
     </StackPanel>
</Grid>

Für die Schaltflächen finden Sie das Attribut IsEnabled, das wir an die Eigenschaften FirstOrPreviousEnabled beziehungsweise NextOrLastEnabled gebunden haben. Wie diese Eigenschaften definiert sind, beschreiben wir weiter unten.

Der Entwurf des Fensters sieht anschließend wie in Bild 1 aus.

Entwurf des Fensters zur Anzeige der Kunden mit Navigations

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar