Moderne Apps

Das Hub-Projekt und -Steuerelement in Windows Store-Apps

Rachel Appel

Rachel AppelFür die Entwicklung unter Windows mit Visual Studio sind die integrierten Projektvorlagen ein guter Ausgangspunkt. Wenn die Entwicklung für den Windows Store (oder andere Microsoft-Technologien) Neuland für Sie ist, können Sie die Vorlagen zum Lernen verwenden. Thema dieses Artikels ist das Hub-Steuerelement, aber ich behandele es im Kontext der Hub-Projektvorlage. Ich werde auf alle wichtigen Punkte eingehen, die Sie über das Hub-Projekt und das Hub-Steuerelement für HTML- und für XAML-Apps wissen müssen.

Das Hub-Projekt ist insbesondere dafür geeignet, umfangreiche Inhalte für die Benutzer bereitzustellen und dazu eine moderne UX zu verwenden. Das liegt daran, dass Sie die Inhalte der App in Teile zerlegen können, die als Hub-Abschnitte bezeichnet werden, und die App die Benutzer daher nicht mit großen Datenmengen visuell überfordert. Meiner persönlichen Meinung nach ist das Hub-Projekt vom ästhetischen Standpunkt her die interessanteste aller Vorlagen für Windows Store-Apps. Das Inhaltslayout besteht aus getrennten Abschnitten, die von den Benutzern einfach zu erfassen sind. Sie können den besten Teil vom Inhalt im Hub-Mittelpunkt, dem „hero“-Abschnitt, und die übrigen Inhaltselemente in Gruppen mit einfacher Zugriffsmöglichkeit präsentieren.

Natürlich ist es nicht obligatorisch, die Vorlagen zu verwenden – Sie können mit einem leeren Projekt beginnen. Vielen Entwicklern fällt es allerdings viel leichter, die Vorlagen anzupassen und zu erweitern, da der Code bereits für Sie eingerichtet ist.

Die Hub-Projektvorlage

Visual Studio 2013 enthält Hub-Projektvorlagen für HTML und XAML. Wenn Sie ein neues HTML-Projekt anhand der Vorlage erstellt haben, sehen Sie einige vertraute Projektordner, zum Beispiel „css“, „images“ und „js“. Die gewohnten Ordner werden durch Hub-spezifische Ordner ergänzt: „pages\hub“, „pages\item“ und „pages\section“. Erwartungsgemäß enthält jeder dieser Ordner Dateien, die dem Zweck in der App entsprechen. Im Projektstamm finden Sie die Datei für das Paketmanifest und die Datei „default.html“, die als Ausgangspunkt der App dient, „default.js“ lädt und Funktionen ausführt, die die Verwaltung der App und des Lebenszyklus betreffen. „default.html“ umfasst nicht nur Verweise auf die Datei „\js\default.js“, sondern auch auf Datei „\js\data.js“, die Beispieldaten enthält, und die Datei „\js\navigator.js“, die für die Navigation zuständig ist. Wenn Sie Ihre Kenntnisse über die Navigation auffrischen möchten, lesen Sie meinen Artikel vom August 2013, „Navigationsgrundlagen in Windows Store-Apps“, unter msdn.microsoft.com/magazine/dn342878. Zusammengefasst ist die Hub-Projektvorlage, wie andere Vorlagen, eine schnelle Methode, um visuell interessante, moderne Apps zu veröffentlichen.

Der Mittelpunkt des Hub-Projekts ist natürlich das Hub-Steuerelement. „default.html“ ist in einer mit der Windows-Bibliothek für JavaScript (WinJS) erstellten App zwar der Ausgangspunkt des Projekts, aber sobald der Ladevorgang abgeschlossen ist, erfolgt die Navigation zur Datei „hub.html“. „hub.html“ wird im Verzeichnis „\pages\hub“ gespeichert und enthält das Hub-Steuerelement. Mit diesem Steuerelement erstellen Sie ein modernes Layout, hinter dem mehr steckt als nur langweilige Quadratgruppen. Stattdessen können Sie mit dem Hub-Steuerelement, gekoppelt mit asynchronem Abrufen von Daten, große Mengen von Daten – oder Daten, die unterschiedliche Gruppen umfassen – auf strukturierte, aber zeitgemäße Weise präsentieren.

Die Hub-Vorlage implementiert das Hub-Navigationsmuster (oder hierarchisches Navigationsmuster). Das bedeutet, dass die Benutzer vom Ausgangspunkt (also der Hub-Seite) auf eine Seite navigieren können, die alle Member eines bestimmten Abschnitts enthält, oder von der Hub-Seite zu einem einzelnen Element navigieren können. Die Vorlage enthält auch die Navigation von einer Abschnittsseite zu einer Elementseite. In der Vorlage findet sich zwar nur Navigationscode zwischen dem Abschnitt 3 und seinen Gruppen und Elementen (siehe Abbildung 1), aber mit den ListView- oder Repeater-Steuerelementen können Sie denselben Typ von Navigation für andere Abschnitte realisieren, wenn das in Ihrer App sinnvoll ist. Abbildung 1 zeigt, wie die standardmäßige Hub-App mit Beispieldaten zur Laufzeit aussieht.

The Hub Control at Run Time for Both HTML and XAML Apps
The Hub Control at Run Time for Both HTML and XAML Apps
The Hub Control at Run Time for Both HTML and XAML Apps
Abbildung 1: Das Hub-Steuerelement für HTML- und für XAML-Apps zur Laufzeit

Mit dem neuartigen Windows kam das Prinzip, den Inhalt in den Mittelpunkt zu stellen, und wie Sie sehen können, setzt die Vorlage genau das um.

Das XAML-Hub-Vorlagenprojekt funktioniert vom Konzept her wie die HTML-Vorlage, mit dem Hub als Haupteinstiegspunkt und der Navigation zu Abschnitten und Details. Die Implementierung unterscheidet sich natürlich, wie Sie an der Ordnerstruktur mit den folgenden Verzeichnissen erkennen können: „Assets“, „Common“, „DataModel“ und „Strings“. Diese Ordner enthalten erwartungsgemäß Ressourcen wie beispielsweise Grafiken, Daten im Ordner „DataModel“ und lokalisierte Zeichenfolgen im Ordner „Strings“. Im Projektstamm befinden sich die folgenden Arbeitsdateien, die zum Ausführen der App erforderlich sind:

  • „App.xaml/.cs“: Die XAML-Entsprechung von „default.html“. Sie enthält etwas Code, der bei der Navigation und allgemeinen Aufgaben hilft.
  • „HubPage.xaml/.cs“: Das Kronjuwel der App, das das Hub-Steuerelement enthält.
  • „ItemPage.xaml/.cs“: Enthält die einzelnen Elemente, zu denen Sie von den Hub- oder Abschnittsseiten navigieren können.
  • „SectionPage.xaml/.cs“: Zeigt alle einzelnen Datenmember, die zu einer bestimmten Gruppe gehören.
  • „Package.appmanifest“: Enthält die App-Einstellungen.

Die Datei „HubPage.xaml“ im XAML-Hub-Vorlagenprojekt zeigt, dass das Hub-Steuerelement fest in einem Grid-Steuerelement platziert ist. Dieses dient als Stammcontainer für die Seite und den Hub.

Im Ordner „DataModel“ ist die Datei „SampleData.json“ gespeichert, die Beispieldaten enthält. Der Ordner enthält auch die Datei „SampleDataSource.cs“, die die JSON-Daten in verwendbare Klassen für die Nutzung in C# oder Visual Basic .NET und die XAML-Datenbindung transformiert. Sie können diese Daten durch eigene ersetzen, vergleichbar mit der Datei „data.js“ in WinJS-Apps.

Der Ordner „Common“ enthält mehrere Dateien, die eine Vielzahl von Aufgaben ausführen, z. B. die Navigation und andere, im Allgemeinen App-bezogene Aufgaben für die Arbeit mit Daten in Ansichtsmodellen. Außerdem befindet sich im Ordner „Common“ die Datei „SuspensionManager.cs“, die Prozesslebenszyklus-Aufgaben ausführt. Der Ordner „Strings“ enthält lokalisierte Zeichenfolgen für die Veröffentlichung in unterschiedlichen Gebietsschemata.

Das Hub-Steuerelement

Die HTML- und XAML-Projektvorlagen verwenden beide das Hub-Steuerelement. In HTML-Apps funktioniert das Hub-Steuerelement genau wie jedes andere WinJS-Steuerelement. Verwenden Sie das data-win-control-Attribut eines HTML-Elements, in der Regel ein <div>, um es als Hub-Steuerelement zu definieren, wie in diesem Code gezeigt:

<div class="hub" data-win-control="WinJS.UI.Hub"></div>

Das bedeutet, dass das WinJS.UI.Hub-Objekt der „Kopf“ hinter dem Hub-Steuerelement ist. Das Hub-Steuerelement agiert als Container für die HubSection-Steuerelemente, die Abschnitte oder Gruppen von Daten definieren. HubSection-Objekte können beliebige gültige HTML-Tags wie zum Beispiel <div>- oder <img>-Tags oder ein WinJS-Steuerelement wie „ListView“ enthalten. Das Hub-Steuerelement in der Datei „hub.html“ umschließt standardmäßig fünf Abschnitte, einen namens „hero“ und vier weitere, die durch ihre Klassenattribute bezeichnet werden („section1„, „section2“ usw.). In den HubSection-Objekten sind <div>- und <img>-Tags die häufigsten untergeordneten Elemente, aber alle gültigen HTML- oder WinJS-Steuerelemente funktionieren, um Daten in einem anderen Layout anzuzeigen. Layoutänderungen sind hervorragend zur Personalisierung von Apps geeignet. Beachten Sie dabei aber die Windows-UX-Richtlinien unter bit.ly/1gBDHaW. Abbildung 2 zeigt ein vollständiges Beispiel des HTML-Codes (zum dazugehörigen CSS komme ich noch), der zum Erstellen eines Hub-Steuerelements mit fünf Abschnitten erforderlich ist. Wenn Sie den Code in Abbildung 2 untersuchen, sehen Sie, dass von den Abschnitten nur Abschnitt 3 navigierbar ist.

Abbildung 2: Der HTML-Code, der das Hub-Steuerelement erstellt

<div class="hub" data-win-control="WinJS.UI.Hub">
  <div class="hero" data-win-control="WinJS.UI.HubSection"></div>
  <div class="section1" data-win-control="WinJS.UI.HubSection"
     data-win-options="{ isHeaderStatic: true }"
     data-win-res="{ winControl: {'header': 'Section1'} }">
    <img src="/images/gray.png" width="420" height="280" />
    <div class="subtext win-type-x-large" data-win-res="
      { textContent: 'Section1Subtext' }"></div>
    <div class="win-type-medium"
       data-win-res="{ textContent: 'DescriptionText' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
    </div>
  </div>
  <div class="section2" data-win-control="WinJS.UI.HubSection" data-win-options="{
 isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section2'} }">
  <div class="item-title win-type-medium" data-win-res="{ textContent: 'Section2ItemTitle' }"></div>
    <div class="article-header win-type-x-large" data-win-res="{ textContent: 'Section2Subtext' }"></div>
    <div class="win-type-xx-small" data-win-res="{ textContent: 'Section2ItemSubTitle' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
    </div>
  </div>
  <div class="section3" data-win-control="WinJS.UI.HubSection" data-win-res="{
 winControl: {'header': 'Section3'} } "data-win-options="{
    onheaderinvoked: select('.pagecontrol').winControl.section3HeaderNavigate }">
    <div class="itemTemplate" data-win-control="WinJS.Binding.Template">
      <img src="#" data-win-bind="src: backgroundImage; alt: title" />
      <div class="win-type-medium" data-win-bind="textContent: title"></div>
      <div class="win-type-small" data-win-bind="textContent: description"></div>
      </div>
      <div class="itemslist win-selectionstylefilled" data-win-control="WinJS.UI.ListView"
        data-win-options="{layout: {type: WinJS.UI.GridLayout},
        selectionMode: 'none', itemTemplate: select('.section3 .itemTemplate'),
        itemDataSource:select('.pagecontrol').winControl.section3DataSource,
         oniteminvoked: select('.pagecontrol').winControl.section3ItemNavigate }">
      </div>
    </div>
  <div class="section4" data-win-control="WinJS.UI.HubSection" data-win-options="{
   isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section4'} }">
    <div class="top-image-row">
      <img src="/images/gray.png" />
    </div>
    <div class="sub-image-row">
      <img src="/images/gray.png" />
      <img src="/images/gray.png" />
      <img src="/images/gray.png" />
    </div>
    <div class="win-type-medium"       data-win-res="{ textContent: 'DescriptionText' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section4Description' }"></span>
      <span data-win-res="{ textContent: 'Section4Description' }"></span>
    </div>
  </div>
</div>

In XAML verwendet das Hub-Steuerelement ein <Hub>-Element, das <Hub.Header>- und <HubSection>-Elemente enthält. Die untergeordneten Überschriften und Abschnitte wiederum enthalten das Grid- und andere XAML-Steuerelemente, wie „StackPanel“, sowie Textblöcke. Abbildung 3 zeigt den erforderlichen XAML-Code, um das Hub-Steuerelement in den Visual Studio-Vorlagen zu erstellen.

Abbildung 3: Der XAML-Code für das Hub-Steuerelement

<Hub SectionHeaderClick="Hub_SectionHeaderClick">
  <Hub.Header>
    <!-- Back button and page title -->
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="80"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <Button  x:Name="backButton" Style="{StaticResource NavigationBackButtonNormalStyle}"
        Margin="-1,-1,39,0"
        VerticalAlignment="Top"
        Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
        AutomationProperties.Name="Back"
        AutomationProperties.AutomationId="BackButton"
        AutomationProperties.ItemType="Navigation Button"/>
      <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}"
        Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1"
        VerticalAlignment="Top" IsHitTestVisible="false" TextWrapping="NoWrap" />
    </Grid>
  </Hub.Header>
  <HubSection Width="780" Margin="0,0,80,0">
    <HubSection.Background>
      <ImageBrush ImageSource="Assets/MediumGray.png" Stretch="UniformToFill" />
    </HubSection.Background>
  </HubSection>
  <HubSection Width="500" x:Uid="Section1Header" Header="Section 1">
    <DataTemplate>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
          </Grid.RowDefinitions>
          <Image Source="Assets/MediumGray.png" Stretch="Fill" Width="420" Height="280"/>
          <TextBlock Style="{StaticResource SubheaderTextBlockStyle}"
            Grid.Row="1" Margin="0,10,0,0" TextWrapping="Wrap"
            x:Uid="Section1Subtitle" Text="Lorem ipsum dolor sit nonumy sed consectetuer ising elit, sed diam"/>
          <TextBlock Style="{StaticResource TitleTextBlockStyle}"
            Grid.Row="2" Margin="0,10,0,0" x:Uid="DescriptionHeader" Text="Description text:"/>
          <TextBlock Style="{StaticResource BodyTextBlockStyle}" Grid.Row="3"
            x:Uid="Section1DescriptionText" Text="Lorem ipsum dolor sit amet... "/>
      </Grid>
    </DataTemplate>
  </HubSection>
  <HubSection Width="520" x:Uid="Section2Header" Header="Section 2">
    <DataTemplate>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Style="{StaticResource TitleTextBlockStyle}"
           Margin="0,0,0,10" x:Uid="ItemTitle" Text="Item Title" />
        <TextBlock Style="{StaticResource SubheaderTextBlockStyle}"
           Grid.Row="1" x:Uid="Section2UnderTitle" Text="Quisque in porta
           lorem dolor amet sed consectetuer ising elit, sed diam non
           my nibh uis mod wisi quip."/>
        <TextBlock Style="{StaticResource SubtitleTextBlockStyle}"
           Grid.Row="2" Margin="0,20,0,0" x:Uid="ItemSubTitle"
           Text="Item Sub Title"/>
        <TextBlock Style="{StaticResource BodyTextBlockStyle}" Grid.Row="3"
          x:Uid="LongText" Text="Lorem ipsum dolor sit amet..."/>
      </Grid>
    </DataTemplate>
  </HubSection>
  <HubSection IsHeaderInteractive="True"
     DataContext="{Binding Section3Items}" d:DataContext="{Binding Groups[3],
     Source={d:DesignData Source=/DataModel/SampleData.json,
     Type=data:SampleDataSource}}" x:Uid="Section3Header" Header="Section 3"
     Padding="40,40,40,32">
    <DataTemplate>
      <GridView
        x:Name="itemGridView"
        ItemsSource="{Binding Items}"
        Margin="-9,-14,0,0"
        AutomationProperties.AutomationId="ItemGridView"
        AutomationProperties.Name="Items In Group"
        ItemTemplate="{StaticResource Standard310x260ItemTemplate}"
        SelectionMode="None"
        IsSwipeEnabled="false"
        IsItemClickEnabled="True"
        ItemClick="ItemView_ItemClick">
      </GridView>
    </DataTemplate>
  </HubSection>
  <HubSection x:Uid="Section4Header" Header="Section 4">
    <DataTemplate>
      <!-- width of 400 -->
      <StackPanel Orientation="Vertical">
        <Grid>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="130"/>
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="270"/>
            <RowDefinition Height="95"/>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
          </Grid.RowDefinitions>
          <Image Source="Assets/MediumGray.png"
             Grid.ColumnSpan="5" Margin="0,0,0,10" Stretch="Fill" />
          <Image Source="Assets/MediumGray.png" Grid.Row="1" Stretch="Fill"/>
           <Image Source="Assets/MediumGray.png" Grid.Row="1"
              Grid.Column="2" Stretch="Fill"/>
          <Image Source="Assets/MediumGray.png" Grid.Row="1"
              Grid.Column="4" Stretch="Fill"/>
          <TextBlock Style="{StaticResource TitleTextBlockStyle}"
             Grid.Row="2" Grid.ColumnSpan="5"  Margin="0,15,0,0"
            x:Uid="DescriptionHeader" Text="Description text:"/>
          <TextBlock Style="{StaticResource BodyTextBlockStyle}"
             Grid.Row="3" Grid.ColumnSpan="5" x:Uid="LongText"
             Text="Lorem ipsum dolor sit amet...."/>
        </Grid>
      </StackPanel>
    </DataTemplate>
  </HubSection>
</Hub>

Sie sehen, dass die XAML-Syntax ausführlicher als die HTML-Syntax ist. Das liegt daran, dass Sie das Layout und die Stile direkt auf der XAML-Seite definieren (obschon XAML-Stile in ein Ressourcenwörterbuch eingefügt werden können), während Sie für die Layout- und Stilregeln in HTML CSS verwenden (zur Formatierung später mehr).

Datenbindung und das Hub-Steuerelement

Wie in vielen anderen Web- oder Clientsprachen verwendet auch WinJS für die Arbeit mit Daten normalerweise Arrays oder JSON (wobei JSON gewöhnlich sowieso in ein Array serialisiert wird). Das trifft auch für das Hub-Projekt zu. Sie können die Daten in „\js\data.js“ durch benutzerdefinierte Daten ersetzen, die in so viele Gruppen unterteilt sind, wie Sie verwenden möchten. In der Datei „data.js“ finden Sie zwei Arrays als Beispieldaten, eine für die Gruppierung und eine für einzelne Elemente, die in eine bestimmte Gruppe gehören. Wenn Sie mit ein paar von den anderen WinJS-Projektvorlagen vertraut sind, werden Sie bemerken, dass es dieselben Beispieldaten sind.

Die Datei „\pages\hub\hub.js“ enthält die Aufrufe von Membern des Data-Namespace, die Gruppen- und Elementdaten abrufen:

var section3Group = Data.resolveGroupReference("group4");
var section3Items = Data.getItemsFromGroup(section3Group);

„section3Group“ und „section3Items“ sind globale Objekte. Abbildung 2 zeigt die Datenbindungssyntax für das ListView-Steuerelement. In „hub.js“ legt der Code nach der ready-Funktion die Hub-Steuerelementeigenschaft „section3DataSource“ fest:

section3DataSource: section3Items.dataSource,

Das Hub-Steuerelement verwendet den vorhergehenden Code zur Datenbindung an „ListView“ (Abbildung 2 zeigt den datengebundenen ListView-Code).

In XAML-Apps, die C# verwenden, sind dieselben Basisvorgänge vorhanden, da der Code aus der Datei „HubPage.xaml.cs“ die unten stehende Deklaration für ein Ansichtsmodell vom Typ „ObservableDictionary“ angibt. Außerdem wird die entsprechende Eigenschaftsdeklaration aufgeführt (hier können Sie Ihre eigenen Daten zurückgeben).

private ObservableDictionary defaultViewModel = new ObservableDictionary();
public ObservableDictionary DefaultViewModel
{
  get { return this.defaultViewModel; }
}

Später in der Datei ruft der Code „GetGroupAsync“ auf, um ein Ansichtsmodell auf Seitenebene einzurichten. Wie schon der Name sagt, wird dieses asynchron ausgeführt: 

var sampleDataGroup = await SampleDataSource.GetGroupAsync("Group-4");

Obwohl der Aufruf Group-4-Daten abruft, weisen Sie ihn einem Ansichtsmodell mit Namen „Section3Items“ zu, um ihn diesen Elementen zuzuordnen. Betrachten Sie den hero-Abschnitt als Abschnitt 0, was bedeutet, dass Elemente des Abschnitts 3 zu den Group-4-Daten passen:

this.DefaultViewModel["Section3Items"] = sampleDataGroup;

Das ist alles, was im Codebehind erforderlich ist. In XAML wird das DataContext-Attribut an „Section3Items“ gebunden. Die anderen Attribute sind für die Datenbindung nicht notwendig, dienen aber als Hilfe für die Entwurfstools in Visual Studio oder Blend, wie durch das d-Namespace gekennzeichnet wird:

<HubSection IsHeaderInteractive="True" DataContext="{Binding Section3Items}" 
  d:DataContext="{Binding Groups[3], Source={d:DesignData
  Source=/DataModel/SampleData.json, Type=data:SampleDataSource}}"
  x:Uid="Section3Header" Header="Section 3" Padding="40,40,40,32">

Bei der Arbeit mit lokalen Beispieldaten haben Sie zahlreiche Datenzugriffsoptionen, darunter File IO, SQLite, Web Storage, IndexedDB, REST-Dienste und Windows Azure, um einige zu nennen. Informationen darüber, welche Datenoptionen verfügbar sind, finden Sie in meinem Artikel „Datenzugriffs- und Datenspeicherungsoptionen in Windows Store-Apps“ vom März 2013 unter msdn.microsoft.com/magazine/jj991982.

Formatieren des Hub-Steuerelements

In Windows Store-Apps, die mit JavaScript erstellt wurden, können Sie das Hub-Steuerelement mit CSS formatieren. Die Datei „\hub\hub.css“ enthält das gesamte Standard-CSS für das Hub-Steuerelement. Fügen Sie eigene Stile hinzu, um die Größe oder das Layout der Elemente zu ändern. Abbildung 4 zeigt das gesamte CSS in „hub.css“. Der Klassenselektor „.hubpage“ verwendet semantische HTML5-Rollenattribute wie beispielsweise „header[role=banner]“ und „section[role=main]“, um die allgemeinen Stile für den Hub zu bestimmen. Das CSS in Abbildung 4 zeigt danach den Nachfolgerselektor „.hubpage .hub .hero“, der den zentralen Abschnitt („hero“) des Hub-Steuerelements erstellt. „hero“ füllt die linke Seite des sichtbaren Bildschirmteils ungefähr zur Hälfte mit einem hellgrauen Hintergrund aus und ist außerdem eine hervorragende Möglichkeit, einen besonderen Teil vom Inhalt dort zu positionieren, wo ihn kein Benutzer verpassen wird! Sie können „hero“ mit vielen Daten füllen, und grafische Daten oder Multimediadaten werden hier sehr ansprechend präsentiert.

Abbildung 4: CSS zum Anpassen und Formatieren des HTML-Hub-Steuerelements

.hubpage header[role=banner] {
  position: relative;
  z-index: 2;
}
.hubpage section[role=main] {
  -ms-grid-row: 1;
  -ms-grid-row-span: 2;
  z-index: 1;
}
.hubpage .hub .win-hub-surface {
  height: 100%;
}
.hubpage .hub .hero {
  -ms-high-contrast-adjust: none;
  background-image: url(/images/gray.png);
  background-size: cover;
  margin-left: -80px;
  margin-right: 80px;
  padding: 0;
  width: 780px;
}
  .hubpage .hub .hero:-ms-lang(
    ar, dv, fa, he, ku-Arab, pa-Arab, prs, ps, sd-Arab,
     syr, ug, ur, qps-plocm) {
    margin-left: 80px;
    margin-right: -80px;
  }
  .hubpage .hub .hero .win-hub-section-header {
    display: none;
  }
  .hubpage .hub .section1 {
    width: 420px;
  }
  .hubpage .hub .section1 .win-hub-section-content {
    overflow-y: hidden;
  }
  .hubpage .hub .section1 .subtext {
    margin-bottom: 7px;
    margin-top: 9px;
  }
.hubpage .hub .section2 {
  width: 440px;
}
  .hubpage .hub .section2 .win-hub-section-content {
    overflow-y: hidden;
  }
  .hubpage .hub .section2 .item-title {
      margin-top: 4px;
      margin-bottom: 10px;
  }
  .hubpage .hub .section2 .article-header {
    margin-bottom: 15px;
  }
.hubpage .hub .section3 {
}
  .hubpage .hub .section3 .itemslist {
    height: 100%;
    margin-left: -10px;
    margin-right: -10px;
    margin-top: -5px;
  }
  .hubpage .hub .section3 .win-container {
    margin-bottom: 36px;
    margin-left: 10px;
    margin-right: 10px;
  }
  .hubpage .hub .section3 .win-item {
      height: 229px;
      width: 310px;
  }
      .hubpage .hub .section3 .win-item img {
        height: 150px;
        margin-bottom: 10px;
        width: 310px;
      }
.hubpage .hub .section4 {
  width: 400px;
}
  .hubpage .hub .section4 .win-hub-section-content {
        overflow-y: hidden;
  }
  .hubpage .hub .section4 .top-image-row {
    height: 260px;
    margin-bottom: 10px;
    width: 400px;
  }
    .hubpage .hub .section4 .top-image-row img {
      height: 100%;
       width: 100%;
    }
.hubpage .hub .section4 .sub-image-row {
  margin-bottom: 20px;
  display: -ms-flexbox;
  -ms-flex-flow: row nowrap;
  -ms-flex-pack: justify;
}
  .hubpage .hub .section4 .sub-image-row img {
    height: 95px;
     width: 130px;
  }

Wie Sie sehen, wird das Hub-Steuerelement vom CSS in Abbildung 4 angepasst und formatiert, und das meiste dient dazu, Layout und Größe der Hub-Abschnitte zu bestimmen. Die Elemente und WinJS-Steuerelemente innerhalb von HubSection-Objekten übernehmen die Stile von „ui-light.css“ oder „ui-dark.css“, bis Sie sie mit eigenen Stilen überschreiben.

HTML-Apps verwenden CSS für die Formatierung. XAML-Apps verwenden XAML für die Formatierung. Das heißt, dass XAML mehrere Attribute hat, die Sie auf Tags anwenden, um Formatierungsdefinitionen durchzusetzen, die als Ressourcen bezeichnet werden. Zum Beispiel ist der Code zur Formatierung von „TextBlock“ das Attribut „Style“, und der Code referenziert einen integrierten Stil (ein statisches Ressourcenwörterbuch) namens „SubheaderTextBlockStyle“:

<TextBlock Style="{StaticResource SubheaderTextBlockStyle} />

Auch das Layout einer Seite ist XAML, da alle Hubs, Raster und andere Elemente Inlinekoordinaten für ihre Bildschirmposition und Größe enthalten. In der gesamten Abbildung 3 sehen Sie, dass es Seitenränder, Positionierungen sowie Zeilen- und Spalteneinstellungen gibt, die die Elemente positionieren, und alle sind inline im XAML aufgeführt. HTML ist ursprünglich eine Webtechnologie, und es ist ein echter Vorteil, durch Verwendung von CSS anstelle von HTML Bandbreite zu sparen. Hier in XAML ist alles clientseitig. Daher ist die Benutzeroberflächen-Zwischenspeicherung kein großes Problem, und die Formatierungen können intern eingefügt werden. Ein Bonus von XAML ist, dass Sie nur sehr wenig tun müssen, um einen reaktionsfähigen Entwurf zu gewährleisten. Stellen Sie einfach sicher, zwei <RowDefinition>-Elemente auf die Höhe von „Auto“ und „*“ festzulegen:

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

Die Zeilen reagieren automatisch auf Veränderungen des App-Ansichtszustands und sorgen somit für ein flüssiges Layout, ohne dass zusätzlicher Code verwendet wird. Abbildung 3 zeigt ein paar Verweise auf Zeilendefinitionen mit automatischer Höhe. 

Verfügbare Beispiele

Nachdem Sie das Hub-Steuerelement geändert, Datenabruf und -bindung ausgeführt und Stile festgelegt haben, ist alles startbereit. Geben Sie der App durch Kacheln, Suche und andere moderne Features zur Integration in Windows den letzten Schliff. Die Hub-Projektvorlage ist eine einfache Möglichkeit, Apps sowohl in HTML als auch in XAML schnell zu erstellen und zu veröffentlichen. Durch die Verwendung des Hub-Navigationsmusters mit dem Hub-Steuerelement programmieren Sie eine effektive und umfangreiche UX, die den modernen Benutzeroberflächenprinzipien entspricht. Beispiele für Hub-Steuerelemente, die viele Aspekte der Windows-App-Entwicklung behandeln, können Sie auf diesen Websites herunterladen:

Rachel Appel ist Beraterin, Autorin, Mentorin und frühere Microsoft-Mitarbeiterin mit über zwanzigjähriger Erfahrung in der IT-Branche. Sie nimmt an wichtigen Branchenkonferenzen wie Visual Studio Live!, DevConnections und MIX als Rednerin teil. Ihr Fachbereich ist die Entwicklung von Lösungen, bei denen geschäftliche und technologische Aspekte in Einklang gebracht werden und in denen führende Microsoft- und offene Webtechnologien zum Einsatz kommen. Besuchen Sie Rachel Appel auf ihrer Website unter rachelappel.com.

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Frank La Vigne (Microsoft).