Windows 8.1 Scrollviewer fixe Header und Spalte

Letztens in einem Vortrag von mir, fiel es mir wie Schuppen von den Augen. Während die Worte über die Lippen flossen, sprach mein Gehirn zu mir. Das ist es! Es geht nicht um Maus, Keyboard oder Touch. Es geht nicht um Tablet, PC oder Phone. Es geht um die Nutzung, die Situation, den Ort. Wir brauchen Bedienkonzepte die genau das Berücksichtigen. Es gilt nicht mehr “Spielekonsole= Wohnzimmer”, “Computer=Schreibtisch”, “Telefon = Küchenwand” mehr.

UX Design wird damit nicht einfacher. Controls helfen dabei konkrete Nutzungsszenarien (sozusagen als Entwurfsmuster) abzudecken. Sehr bekanntes Entwurfsmuster ist die Tabelle. Eine oft gehörte Frage in den ppedv Trainings ist: “wie kann man eine Excel ähnliche Tabelle im Formular darstellen?” Neben den vielen Feldern in den Spalten und Reihen, ist die Eigenheit von Excel, das die Bezeichner (Beschriftung) im Kopf und Links fixiert sind.

Dies klappt nun auch mit dem XAML Scrollviewer aus Windows 8.1 (METRO, Modern UI). Neu hinzugekommen sind drei Templates

  • TopLeftHeader
  • TopHeader
  • LeftHeade

Im folgenden Beispiel werden Ozonwerte von Österreichischen Messstationen dargestellt. Es sind mehr Zeilen als auf das Display passen und auch mehr Spalten. Der Benutzer kann dann in beide Richtungen scrollen.

image

Hier wird die Spalte Ort in einem eigenen Listview dargestellt um diese Werte in die Spalte LeftHeader zu bekommen. Die Überschrift in der Zeile TopHeader ist ident mit den gebundenen Werten und Darstellung in der zweiten Listview. Diese zweite Listview mit den eigentlichen Daten wird letztendlich vom Scrollviewer umschlossen und stellt den großen nicht darstellbaren Bereich dar. Über die Attribute Horizontal – und VerticalScrollmode wird unterbunden, das man zwei bzw. vier Scrollbalken zu Gesicht bekommt.

   1:   <ScrollViewer Width="500" Margin="133,63,0,0"
   2:                        HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Visible">
   3:       <ScrollViewer.TopLeftHeader>
   4:                  <Rectangle  Fill="White" Width="276" Height="38">
   5:                     </Rectangle>
   6:      </ScrollViewer.TopLeftHeader>
   7:      <ScrollViewer.TopHeader>
   8:              <StackPanel Orientation="Horizontal" Background="White" >
   9:                     <TextBlock Text="StationID" Width="100" ></TextBlock>
  10:                      <TextBlock Text="Zeit" Width="140" ></TextBlock>
  11:                      <TextBlock Text="Breitengrad" Width="100"></TextBlock>
  12:                      <TextBlock Text="Längengrad" Width="100"></TextBlock>
  13:                      <TextBlock Text="ozon 1h" Width="100" ></TextBlock>
  14:                      <TextBlock Text="Max ozon 1h" Width="100"></TextBlock>
  15:                      <TextBlock Text="ozon 8h" Width="100" ></TextBlock>
  16:                  </StackPanel>
  17:        </ScrollViewer.TopHeader>
  18:        <ScrollViewer.LeftHeader>
  19:               <ListView   Background="DarkGray" 
  20:  ScrollViewer.HorizontalScrollMode="Disabled"
  21:   ScrollViewer.VerticalScrollMode="Disabled"
  22:                    x:Name="liste1" HorizontalAlignment="Left"  VerticalAlignment="Top" 
  23:                              SelectionMode="None" >
  24:                      <ListView.ItemTemplate>
  25:                          <DataTemplate>
  26:                                  <TextBlock Text="{Binding name}" Width="250"></TextBlock>
  27:                          </DataTemplate>
  28:                      </ListView.ItemTemplate>
  29:                  </ListView>
  30:              </ScrollViewer.LeftHeader>
  31:          <ListView SelectionMode="None"  
  32:   ScrollViewer.HorizontalScrollMode="Disabled" 
  33:  ScrollViewer.VerticalScrollMode="Disabled"
  34:                    x:Name="liste0" HorizontalAlignment="Left"  VerticalAlignment="Top"  >
  35:              <ListView.ItemTemplate>
  36:                  <DataTemplate>
  37:                      <StackPanel Orientation="Horizontal">
  38:                          <TextBlock Text="{Binding id}" Width="100"></TextBlock>
  39:                          <TextBlock Text="{Binding timestamp_utc}" Width="140"></TextBlock>
  40:                          <TextBlock Text="{Binding lat}" Width="100"></TextBlock>
  41:                          <TextBlock Text="{Binding lon}" Width="100"></TextBlock>
  42:                          <TextBlock Text="{Binding ozon1h}" Width="100"></TextBlock>
  43:                          <TextBlock Text="{Binding ozon1hMax}" Width="100"></TextBlock>
  44:                          <TextBlock Text="{Binding ozon8h}" Width="100"></TextBlock>
  45:                      </StackPanel>
  46:                  </DataTemplate>
  47:              </ListView.ItemTemplate>
  48:          </ListView>
  49:  </ScrollViewer>

Anmerkung: Da ein Listview auch intern u.a. aus einem Scrollviewer besteht, erscheint es mir etwas seltsam dem inneren Scrollviewer das Scrollen abzugewöhnen und dafür einen außen rum zu definieren. Passender wäre es per Setter in das innere Template einzugreifen.

Kommentare sind geschlossen