Verwenden der Fingereingabe in Hilo (Windows Store-Apps mit C++ und XAML)

Applies to Windows only

Aus: Umfassende Entwicklung einer Windows Store-App mit C++ und XAML: Hilo

Leitfaden-Logo

Vorherige Seite | Nächste Seite

Hilo bietet Beispiele für Tipp-, Zieh-, Streif-, Zusammendrück-, Aufzieh- und Drehbewegungen. Wir verwenden XAML-Datenbindung, um Windows-Standardsteuerelemente, die Fingereingabegesten verwenden, mit dem Ansichtsmodell zu verbinden, das diese Gesten implementiert. An dieser Stelle wird kurz erläutert, wie wir die Windows 8-Sprache für die Fingereingabe auf Hilo angewendet haben, damit auf jedem Gerät eine großartige Benutzererfahrung geboten wird.

Download

Herunterladen des Hilo-Beispiels
Buch herunterladen (PDF)

Anweisungen zu dem heruntergeladenen Code finden Sie unter Erste Schritte mit Hilo.

Sie erfahren Folgendes:

  • Verwendung der Windows 8-Sprache für die Toucheingabe in Hilo.
  • Unterstützung von Geräten, die keine Toucheingabe ermöglichen, durch die Windows-Runtime

Betrifft

  • Windows-Runtime für Windows 8
  • Visual C++-Komponentenerweiterungen (C++/CX)
  • XAML

Zum Bereitstellen einer großartigen Benutzererfahrung gehört, dass die App sowohl auf einem herkömmlichen Desktopcomputer als auch auf einem kleinen Tablet barrierefrei ist und intuitiv verwendet werden kann. Für Hilo stellten wir die Fingereingabe in den Vordergrund unserer UX-Planung, da wir erkannten, dass die Fingereingabe der Schlüssel für eine komfortable Interaktion zwischen Benutzer und App ist.

Wie in Entwerfen der Hilo-UX beschrieben, ist die Fingereingabe nicht lediglich eine Alternative zur Verwendung der Maus. Wir wollten die Fingereingabe zu einem hervorragenden Teil der App machen, da sie zu einer persönlichen Verbindung zwischen dem Benutzer und der App beitragen kann. Die Fingereingabe ist außerdem eine höchst natürliche Methode, mit der Benutzer ihre Fotos zuschneiden und drehen können. Wir erkannten außerdem, dass Benutzer mit semantischem Zoom besonders einfach in einer einzelnen Ansicht in einer großen Gruppe von Bildern navigieren können. Wenn der Benutzer auf der Seite zum Durchsuchen die Zusammendrückbewegung verwendet, ändert sich die Ansicht in eine kalenderbasierte Ansicht. Benutzer können dann Fotos schneller durchsuchen.

In Hilo wird die Windows 8-Sprache für Fingereingaben verwendet. Wir verwenden aus den folgenden Gründen die Standard-Fingereingabegesten von Windows:

  • Die Windows-Runtime ermöglicht ein einfaches Arbeiten mit diesen Gesten.
  • Wir wollten die Benutzer nicht durch das Erstellen von benutzerdefinierten Interaktionen verwirren.
  • Wir möchten, dass Benutzer die App mit Gesten erkunden, die sie bereits kennen, und keine neuen Gesten erlernen müssen.

Hinweis  

Das MVVM (Model-View-ViewModel)-Muster spielt beim Definieren von Benutzerinteraktionen eine wichtige Rolle. Wir implementieren die App-UI und -Modelle mithilfe von Ansichten und kapseln den Status und die Aktionen der App mithilfe von Ansichtsmodellen. Weitere Informationen zu MVVM finden Sie unter Verwenden des MVVM-Musters.

Die Windows 8-Sprache für die Fingereingabe wird im Dokument Design für Interaktion per Fingereingabe (Windows Store-Apps) erläutert. In den folgenden Abschnitten wird beschrieben, wie wir die Windows 8-Sprache für die Fingereingabe auf Hilo angewendet haben.

[Oben]

Gedrückt halten: Lernen

Mit dieser Interaktion per Fingereingabe können Sie eine QuickInfo, ein Kontextmenü oder ein ähnliches Element anzeigen, ohne den Benutzer zu einer Interaktion zu zwingen. Mit der Gedrückthaltbewegung auf der Bildansichtsseite kann der Benutzer Informationen zu einem Foto, z. B. Dateiname, Abmessungen und Aufnahmedatum, erhalten.

Gedrückthalten zum Anzeigen von Fotoeigenschaften

Wir verwendeten zum Implementieren von Gedrückthalten das Popup-Steuerelement. Das resultierende Popupmenü enthält ein Grid, das an die Fotodaten gebunden ist. Wir mussten keine Eigenschaften festlegen, um das Popupmenü zunächst auszublenden, da Popupmenüs standardmäßig ausgeblendet sind.

Hier der XAML-Code für den Popup.

ImageView.xaml


<Popup x:Name="ImageViewFileInformationPopup"
       AutomationProperties.AutomationId="ImageViewFileInformationPopup">
    <Popup.Child>
        <Border Background="{StaticResource GreySplashScreenColor}"
                BorderBrush="{StaticResource HiloBorderBrush}"
                BorderThickness="3">
            <Grid Margin="10">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Image Source="{Binding Path=CurrentPhotoImage.Thumbnail}" 
                       Height="105" 
                       Width="105" 
                       Stretch="UniformToFill" />
                <StackPanel Grid.Column="1" 
                            Margin="10,0,10,0">
                    <TextBlock Foreground="{StaticResource ApplicationForegroundThemeBrush}" 
                               FontWeight="Bold"
                               Text="{Binding Path=CurrentPhotoImage.Name}" 
                               TextWrapping="Wrap"/>
                    <TextBlock Foreground="{StaticResource ApplicationForegroundThemeBrush}"
                               Text="{Binding Path=CurrentPhotoImage.DisplayType}"/>
                    <TextBlock Foreground="{StaticResource ApplicationForegroundThemeBrush}" 
                               Text="{Binding Path=CurrentPhotoImage.Resolution}" />
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Foreground="{StaticResource ApplicationForegroundThemeBrush}" 
                                   Text="{Binding Path=CurrentPhotoImage.FormattedDateTaken}" />
                        <TextBlock Foreground="{StaticResource ApplicationForegroundThemeBrush}"
                                   Margin="4,0,0,0"
                                   Text="{Binding Path=CurrentPhotoImage.FormattedTimeTaken}" />
                    </StackPanel>
                    <TextBlock Foreground="{StaticResource ApplicationForegroundThemeBrush}" 
                               Text="{Binding Path=CurrentPhotoImage.FileSize, Converter={StaticResource FileSizeConverter}}" />
                    <TextBlock Foreground="{StaticResource ApplicationForegroundThemeBrush}"
                               Margin="0,20,0,0"
                               Text="{Binding Path=CurrentPhotoImage.FormattedPath}" />
                </StackPanel>
            </Grid>
        </Border>
    </Popup.Child>
</Popup>


Die Methoden OnImagePointerPressed, OnImagePointerReleased und OnImagePointerMoved behandeln das Ereignis PointerPressed, PointerReleased bzw. PointerMoved. Die OnImagePointerPressed-Methode legt ein Flag fest, das angibt, dass der Zeiger gedrückt wird. Wenn die linke Maustaste gedrückt wird (die IsLeftButtonPressed-Methode gibt für die Fingereingabe immer true zurück), wird das Popupmenü mit einem Abstand von 200 Pixeln von der linken und oberen Kante des aktuellen Berührungspunkts positioniert.

ImageView.xaml.cpp


void Hilo::ImageView::OnImagePointerPressed(Object^ sender, PointerRoutedEventArgs^ e)
{
    m_pointerPressed = true;
    PointerPoint^ point = e->GetCurrentPoint(PhotoGrid);
    m_pointer = point->Position;
    if (point->Properties->IsLeftButtonPressed)
    {
        ImageViewFileInformationPopup->HorizontalOffset = point->Position.X - 200;
        ImageViewFileInformationPopup->VerticalOffset = point->Position.Y - 200;
        ImageViewFileInformationPopup->IsOpen = true;
    }
}


Hinweis  Das Popupmenü wird auf der linken Seite des Zeigers dargestellt, da die meisten Menschen Rechtshänder sind. Wenn der Benutzer mit dem Zeigefinger die Oberfläche berührt, kann die rechte Hand des Benutzers ein Popupmenü blockieren, das auf der rechten Seite des Zeigers angezeigt wird.

Die OnImagePointerReleased-Methode schließt das Popupmenü. Sie wird aufgerufen, wenn der Benutzer den Zeiger loslässt.

ImageView.xaml.cpp


void Hilo::ImageView::OnImagePointerReleased(Object^ sender, PointerRoutedEventArgs^ e)
{
    if (m_pointerPressed)
    {
        ImageViewFileInformationPopup->IsOpen = false;
        m_pointerPressed = false;
    }
}


Die OnImagePointerMoved-Methode schließt ebenfalls das Popupmenü. Die OnImagePointerPressed-Methode legt ein Flag fest und speichert die aktuelle Zeigerposition, da die OnImagePointerMoved-Methode auch aufgerufen wird, wenn der Zeiger zunächst gedrückt wird. Daher ist es nur erforderlich, die aktuelle Position mit der gespeicherten Position zu vergleichen und das Popupmenü zu schließen, wenn sich die Position geändert hat.

ImageView.xaml.cpp


void Hilo::ImageView::OnImagePointerMoved(Object^ sender, PointerRoutedEventArgs^ e)
{
    if (m_pointerPressed)
    {
        PointerPoint^ point = e->GetCurrentPoint(PhotoGrid);
        if (point->Position != m_pointer)
        {
            OnImagePointerReleased(sender, e);
        }
    }
}


Das Popup definiert außerdem ein Converter-Objekt, das Bytes in Kilobytes oder Megabytes umwandelt, damit die Bildgröße auf dem Datenträger besser lesbar ist. Wir erkannten, dass sich Konverter gut dazu eignen, Daten zu binden, die auf unterschiedliche Weise angezeigt werden sollen. Weitere Informationen zu Konvertern finden Sie unter Datenkonverter in diesem Handbuch.

Kann das Holding-Ereignis verwendet werden?   Wir erwogen, das UIElement::Holding-Ereignis zu verwenden. Dieses Ereignis ist jedoch für Apps vorgesehen, die nur auf Berührungseingaben und nicht auf Zeigereingaben wie z. B. Eingaben mit der Maus reagieren. Wir zogen auch das GestureRegognizer::Holding-Ereignis in Betracht. GestureRecognizer wird jedoch nicht für Windows Store-Apps mit Verwendung von XAML empfohlen, da Gestikerkennungsfunktionen von XAML-Steuerelementen bereitgestellt werden.

[Oben]

Tippen: Hauptaktion

Durch das Tippen auf ein Element wird dessen primäre Aktion aufgerufen. Beispielsweise tippen Sie im Zuschneidmodus auf den Zuschneidbereich, um das Bild zuzuschneiden.

Zuschneidmodus in Hilo

Zum Implementieren von Zuschneiden ordneten wir ein Grid-Element über dem Zuschneidsteuerelement an und implementierten das Tapped-Ereignis. Wir verwenden ein Grid-Steuerelement, damit der gesamte Zuschneidbereich und nicht nur das Steuerelement, das das Zuschneidrechteck definiert, Tippereignisse empfängt.

Hier der XAML-Code für den Grid.

CropImageView.xaml


<Grid Background="Transparent"
      HorizontalAlignment="Stretch"
      VerticalAlignment="Stretch"
      Tapped="OnCropRectangleTapped">
</Grid>


Die Ansicht für die Seite zum Zuschneiden von Bildern behandelt das Tapped-Ereignis, indem sie den Vorgang an das Ansichtsmodell weiterleitet.

CropImageView.xaml.cpp


void CropImageView::OnCropRectangleTapped(Object^ sender, TappedRoutedEventArgs^ e)
{
    if (!m_cropImageViewModel->InProgress)
    {
        m_cropImageViewModel->CropImageAsync(Photo->ActualWidth);
    }
}


Das Ansichtsmodell für die Seite zum Zuschneiden von Bildern schneidet das Bild zu und ruft dann die BindableBase::OnPropertyChanged-Methode von Hilo auf, um der Ansicht mitzuteilen, dass der Vorgang abgeschlossen ist. In Verwenden des MVVM-Musters in diesem Handbuch wird erläutert, wie Hilo mit Benachrichtigungen über geänderte Ereignisse Statusänderungen mitteilt.

CropImageViewModel.cpp


task<void> CropImageViewModel::CropImageAsync(float64 actualWidth)
{
    assert(IsMainThread());
    ChangeInProgress(true);

    // Calculate crop values
    float64 scaleFactor = m_image->PixelWidth / actualWidth;
    unsigned int xOffset = safe_cast<unsigned int>((m_cropOverlayLeft - m_left) * scaleFactor);
    unsigned int yOffset = safe_cast<unsigned int>((m_cropOverlayTop - m_top) * scaleFactor);
    unsigned int newWidth = safe_cast<unsigned int>(m_cropOverlayWidth * scaleFactor); 
    unsigned int newHeight = safe_cast<unsigned int>(m_cropOverlayHeight * scaleFactor);

    if (newHeight < MINIMUMBMPSIZE || newWidth < MINIMUMBMPSIZE)
    {
        ChangeInProgress(false);
        m_isCropOverlayVisible = false;
        OnPropertyChanged("IsCropOverlayVisible");
        return create_empty_task();
    }

    m_cropX += xOffset;
    m_cropY += yOffset;

    // Create destination bitmap
    WriteableBitmap^ destImage = ref new WriteableBitmap(newWidth, newHeight);

    // Get pointers to the source and destination pixel data
    byte* pSrcPixels = GetPointerToPixelData(m_image->PixelBuffer, nullptr);
    byte* pDestPixels = GetPointerToPixelData(destImage->PixelBuffer, nullptr);
    auto oldWidth = m_image->PixelWidth;

    return create_task([this, xOffset, yOffset, newHeight, newWidth, oldWidth, pSrcPixels, pDestPixels] () {
        assert(IsBackgroundThread());
        DoCrop(xOffset, yOffset, newHeight, newWidth, oldWidth, pSrcPixels, pDestPixels);
    }).then([this, destImage](){
        assert(IsMainThread());

        // Update image on screen
        m_image = destImage;
        OnPropertyChanged("Image");
        ChangeInProgress(false);
    }, task_continuation_context::use_current()).then(ObserveException<void>(m_exceptionPolicy));
}


[Oben]

Ziehen: Verschiebung

In Hilo erfolgt die Navigation zwischen Bildern in einer Sammlung mithilfe der Ziehbewegung. Wenn Sie beispielsweise zu einem Bild navigieren, können Sie mit der Ziehbewegung zum vorherigen oder nächsten Bild in der Auflistung navigieren.

Wenn Sie ein Bild anzeigen, können Sie außerdem mithilfe des Bildstreifens, der angezeigt wird, wenn Sie die App-Leiste aktivieren, schnell zu einem Bild in der aktuellen Auflistung schwenken. Zum Implementieren des Bildstreifens verwendeten wir das GridView-Steuerelement.

Der Bildstreifen, der auf der oberen App-Leiste angezeigt wird

Hier der XAML-Code für den GridView.

ImageView.xaml


<GridView x:Name="PhotosFilmStripGridView"
          Grid.Column="1"
          AutomationProperties.AutomationId="PhotosFilmStripGridView"
          IsItemClickEnabled="False"
          ItemContainerStyle="{StaticResource FilmStripGridViewItemStyle}"
          ItemsSource="{Binding Photos}"
          SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}"
          SelectionMode="Single"
          VerticalAlignment="Center">
    <GridView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Height="138" Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </GridView.ItemsPanel>
    <GridView.ItemTemplate>
        <DataTemplate>
            <Border>
                <Image Source="{Binding Path=Thumbnail}" 
                       Height="138" 
                       Width="200" 
                       Stretch="UniformToFill" />
            </Border>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>


Die Verwendung des GridView-Steuerelements bietet den Vorteil, dass es über integrierte Fingereingabefunktionen verfügt, sodass kein zusätzlicher Code und keine zusätzliche Logik benötigt werden.

[Oben]

Streifen: Auswählen, Befehle und Schieben

Bei der Streifbewegung ziehen Sie den Finger im rechten Winkel zur Schwenkrichtung, um Objekte auszuwählen. Wenn in Hilo eine Seite mehrere Bilder enthält, können Sie mit dieser Bewegung ein Bild auswählen. Wenn die App-Leiste angezeigt wird, gelten die angezeigten Befehle für das ausgewählte Bild. ListView, GridView und weitere Steuerelemente bieten integrierte Unterstützung für die Auswahl. Mit der SelectedItem-Eigenschaft können Sie das ausgewählte Element abrufen oder festlegen.

Auf der App-Leiste werden Befehle für das ausgewählte Foto angezeigt

[Oben]

Zusammendrücken/Aufziehen: Zoom

Die Zusammendrück- und Aufziehbewegung dienen nicht nur zum Vergrößern oder zum Ausführen von optischem Zoom. In Hilo wird semantischer Zoom zum Navigieren zwischen großen Gruppen von Bildern verwendet. Mit semantischem Zoom können Sie zwischen zwei verschiedenen Ansichten des gleichen Inhalts umschalten. In der Regel gibt es eine Hauptansicht des Inhalts und eine zweite Ansicht, die Benutzern die schnelle Navigation im Inhalt ermöglicht. (Weitere Informationen zu semantischem Zoom finden Sie in Hinzufügen von Steuerelementen vom Typ "SemanticZoom".)

Wenn Sie auf der Abbildbrowserseite die Ansicht verkleinern, ändert sich die Ansicht in eine kalenderbasierte Ansicht. In der Kalenderansicht werden die Monate hervorgehoben, die Fotos enthalten. Sie können dann die Ansicht wieder vergrößern, um die bildbasierte Monatsansicht anzuzeigen.

Die kalenderbasierte Bildansicht

Zum Implementieren von semantischem Zoom verwendeten wir das SemanticZoom-Steuerelement. Sie geben im XAML den ZoomedInView-Abschnitt und den ZoomedOutView-Abschnitt an,um das Verhalten für die vergrößerte bzw. verkleinerte Ansicht zu definieren.

Für die vergrößerte Ansicht wird ein GridView angezeigt, das an Miniaturansichten von Fotos gebunden wird, die nach Monat gruppiert sind. In der Rasteransicht wird außerdem für jede Gruppe eine Kachel (der Monat und das Jahr) angezeigt. Die ImageBrowserViewModel::MonthGroups-Eigenschaft und die MonthGroup-Klasse von Hilo legen fest, welche Fotos im Raster angezeigt werden. Die MonthGroup-Klasse definiert außerdem den Titel der Gruppe.

Hier der XAML-Code für den ZoomedInView.

ImageBrowserView.xaml


<SemanticZoom.ZoomedInView>
    <GridView x:Name="MonthPhotosGridView" 
              AutomationProperties.AutomationId="MonthPhotosGridView"
              AutomationProperties.Name="Month Grouped Photos"
              ItemsSource="{Binding Source={StaticResource MonthGroupedItemsViewSource}}" 
              ItemContainerStyle="{StaticResource HiloGridViewItemStyle}"
              ItemClick="OnPhotoItemClicked"
              IsItemClickEnabled="True"
              Padding="116,0,40,46"
              SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
              SelectionMode="Single">


Die ItemsSource-Eigenschaft gibt die Elemente für das Steuerelement an. MonthGroupedItemsViewSource ist eine CollectionViewSource, die die Quelldaten für das Steuerelement bereitstellt.

ImageBrowserView.xaml


<CollectionViewSource
    x:Name="MonthGroupedItemsViewSource"
    d:Source="{Binding MonthGroups, Source={d:DesignInstance Type=local:DesignTimeData, IsDesignTimeCreatable=True}}"
    Source="{Binding MonthGroups}"
    IsSourceGrouped="true"
    ItemsPath="Items"/>


Die MonthGroups-Eigenschaft im Ansichtsmodell ((ImageBrowserViewModel) gibt die Daten an, die an die Rasteransicht für die vergrößerte Ansicht gebunden werden. MonthGroups ist eine Auflistung von IPhotoGroup-Objekten. In Hilo ist die IPhotoGroup-Schnittstelle definiert, um den Titel der Gruppe und Informationen über die einzelnen Fotos bereitzustellen.

Für die verkleinerte Ansicht wird ein GridView angezeigt, das an gefüllte Rechtecke für Kalendermonate gebunden wird, die nach Jahr gruppiert sind (die ImageBrowserViewModel::YearGroups-Eigenschaft sowie die YearGroup-Klasse und die MonthBlock-Klasse von Hilo definieren den Titel und die Monate, die Fotos enthalten).

Hier der XAML-Code für den ZoomedOutView.

ImageBrowserView.xaml


<SemanticZoom.ZoomedOutView>
    <GridView x:Name="YearPhotosGridView" 
              AutomationProperties.AutomationId="YearPhotosGridView"
              AutomationProperties.Name="Year Grouped Photos"
              ItemsSource="{Binding Source={StaticResource YearGroupedItemsViewSource}}"
              IsItemClickEnabled="True"
              Padding="116,0,40,46"
              SelectionMode="None">


Die YearGroupedItemsViewSource ähnelt MonthGroupedItemsViewSource, jedoch wird sie an Daten gebunden, die nach Jahr gruppiert sind.

Weitere Informationen zu semantischem Zoom finden Sie unter Schnellstart: Hinzufügen von Steuerelementen vom Typ "SemanticZoom", Hinzufügen von Steuerelementen vom Typ "SemanticZoom", Richtlinien für semantischen Zoom und XAML – Beispiel für GridView-Gruppierung und SemanticZoom.

[Oben]

Drehen

In der Ansicht zum Drehen von Bildern können Sie das Bild mithilfe von zwei Fingern drehen. Wenn Sie die Finger vom Bild lösen, wird das Bild im nächsten 90-Grad-Winkel fixiert.

Drehen eines Bilds um 90 Grad

Die RotateImageView-Klasse definiert die UX zum Drehen eines Bilds, und die RotateImageViewModel-Klasse definiert das entsprechende Ansichtsmodell. Da RotateImageView von Control erbt, empfängt sie Ereignisse, wenn der Benutzer Objekte bearbeitet. Um Bearbeitungsereignisse für das Bildsteuerelement der Drehbewegung zu empfangen, ist in Hilo im XAML für das Image die ManipulationMode-Eigenschaft festgelegt.

Hier der XAML-Code für den Image.

RotateImageView.xaml


<Image x:Name="Photo" 
       AutomationProperties.AutomationId="ImageControl" 
       HorizontalAlignment="Center"
       ManipulationMode="Rotate"
       Margin="{Binding ImageMargin}"
       RenderTransformOrigin="0.5, 0.5"
       Source="{Binding Photo.Image}"  
       VerticalAlignment="Center">


Die RotateImageView-Klasse überschreibt die OnManipulationDelta-Methode und die OnManipulationCompleted-Methode, um Drehungsereignisse zu behandeln. Die OnManipulationDelta-Methode aktualisiert den Drehwinkel, und die OnManipulationCompleted-Methode fixiert die Drehung am nächsten 90-Grad-Wert.

Achtung  Diese Ereignishandler sind für die gesamte Seite definiert. Wenn die Seite mehrere Elemente enthält, benötigen Sie zusätzliche Logik, um das zu bearbeitende Objekt zu bestimmen.

RotateImageView.xaml.cpp


void RotateImageView::OnManipulationDelta(ManipulationDeltaRoutedEventArgs^ e)
{
    m_viewModel->RotationAngle += e->Delta.Rotation;
}

void RotateImageView::OnManipulationCompleted(ManipulationCompletedRoutedEventArgs^ e)
{
    m_viewModel->EndRotation();
}


RotateImageViewModel.cpp


void RotateImageViewModel::EndRotation()
{
    auto quarterTurns = (RotationAngle / 90);
    auto nearestQuarter = (int)floor(quarterTurns + 0.5) % 4;
    RotationAngle = (float64)nearestQuarter * 90;
}


Ein RenderTransform für das Bild bindet die RotationAngle-Eigenschaft im Ansichtsmodell an das angezeigte Bild.

RotateImageView.xaml


<Image.RenderTransform>
    <RotateTransform 
        x:Name="ImageRotateTransform"  
        Angle="{Binding RotationAngle}" />
</Image.RenderTransform>


Hilo ordnet mithilfe eines Locators für Ansichtsmodelle Ansichten den entsprechenden Ansichtsmodellen zu. Weitere Informationen über die Verwendung von Locators für Ansichtsmodelle in Hilo finden Sie unter Verwenden des MVVM-Musters.

[Oben]

Vom Rand aus streifen: App-Befehle

Wenn relevante Befehle anzuzeigen sind und der Benutzer eine Streifbewegung von der unteren oder oberen Kante des Bildschirms ausführt, wird in Hilo die App-Leiste angezeigt.

Für jede Seite können eine Navigationsleiste, eine untere App-Leiste oder beide Leisten definiert sein. Beispielsweise werden in Hilo beide App-Leisten angezeigt, wenn Sie ein Bild anzeigen und die App-Leiste aktivieren.

Im Folgenden ist die Navigationsleiste dargestellt:

Die obere App-Leiste

Dies ist die untere App-Leiste für das gleiche Foto.

Die untere App-Leiste

Verwenden Sie im XAML die Page::TopAppBar-Eigenschaft zum Definieren der Navigationsleiste und die Page::BottomAppBar-Eigenschaft zum Definieren der unteren App-Leiste. Jede dieser App-Leisten enthält ein AppBar-Steuerelement, in dem sich die UI-Komponenten der App-Leiste befinden. Nachfolgend wird das XAML für die untere App-Leiste der Bildansichtsseite gezeigt. Diese App-Leiste enthält die Befehle zum Aufrufen der Modi zum Drehen, Zuschneiden oder Anwenden des Cartooneffekts auf das Bild.

ImageView.xaml


<local:HiloPage.BottomAppBar>
    <AppBar x:Name="ImageViewBottomAppBar"
            x:Uid="AppBar"
            AutomationProperties.AutomationId="ImageViewBottomAppBar"
            Padding="10,0,10,0">
        <Grid>
            <StackPanel HorizontalAlignment="Left" 
                        Orientation="Horizontal">
                <Button x:Name="RotateButton"
                        x:Uid="RotateAppBarButton"
                        Command="{Binding RotateImageCommand}" 
                        Style="{StaticResource RotateAppBarButtonStyle}" 
                        Tag="Rotate" />
                <Button x:Name="CropButton"
                        x:Uid="CropAppBarButton"
                        Command="{Binding CropImageCommand}"
                        Style="{StaticResource CropAppBarButtonStyle}"
                        Tag="Crop" />
                <Button x:Name="CartoonizeButton"
                        x:Uid="CartoonizeAppBarButton"
                        Command="{Binding CartoonizeImageCommand}"
                        Style="{StaticResource CartoonEffectAppBarButtonStyle}"
                        Tag="Cartoon effect" />
                <Button x:Name="RotateButtonNoLabel"
                        Command="{Binding RotateImageCommand}" 
                        Style="{StaticResource RotateAppBarButtonNoLabelStyle}" 
                        Tag="Rotate"
                        Visibility="Collapsed">
                    <ToolTipService.ToolTip>
                        <ToolTip x:Uid="RotateAppBarButtonToolTip" />
                    </ToolTipService.ToolTip>
                </Button>
                <Button x:Name="CropButtonNoLabel"
                        Command="{Binding CropImageCommand}"
                        Style="{StaticResource CropAppBarButtonNoLabelStyle}"
                        Tag="Crop"
                        Visibility="Collapsed">
                    <ToolTipService.ToolTip>
                        <ToolTip x:Uid="CropAppBarButtonToolTip" />
                    </ToolTipService.ToolTip>
                </Button>
                <Button x:Name="CartoonizeButtonNoLabel"
                        Command="{Binding CartoonizeImageCommand}"
                        Style="{StaticResource CartoonEffectAppBarButtonNoLabelStyle}"
                        Tag="Cartoon effect"
                        Visibility="Collapsed">
                    <ToolTipService.ToolTip>
                        <ToolTip x:Uid="CartoonizeAppBarButtonToolTip" />
                    </ToolTipService.ToolTip>
                </Button>
            </StackPanel>
        </Grid>
    </AppBar>
</local:HiloPage.BottomAppBar>


Achtung  In der Regel sollte die App-Leiste nicht angezeigt werden, wenn keine relevanten Befehle anzuzeigen sind. Beispielsweise bindet die Haupthubseite die AppBar::IsOpen-Eigenschaft an die MainHubViewModel::IsAppBarOpen-Eigenschaft im Ansichtsmodell. AppBar::IsOpen steuert, ob die App-Leiste angezeigt wird. Die Eigenschaft wird festgelegt, wenn ein Objekt ausgewählt ist, und deaktiviert, wenn kein Objekt festgelegt ist.

Weitere Informationen zum Hinzufügen von App-Leisten finden Sie unter Hinzufügen von App-Leisten und Beispiel für XAML-App-Leisten-Steuerelement.

[Oben]

Vom Rand aus streifen: Systembefehle

Da die Interaktion per Fingereingabe unter Umständen weniger genau ist als andere Zeigegeräte, z. B. die Maus, ließen wir einen ausreichenden Abstand zwischen den Steuerelementen und der Bildschirmkante. Wir versuchten außerdem, auf allen Seiten einen gleich großen Rand zu verwenden. Wir verwendeten die Projektvorlagen von Visual Studio, um empfohlene Ränder festzulegen. Da wir die Kanten des Bildschirms frei ließen, kann der Benutzer problemlos eine Streifbewegung von der Kante des Bildschirms ausführen, um die App-Leisten, Knöpfe oder zuvor verwendete Apps anzuzeigen.

[Oben]

Und was ist mit Geräten, die keine Fingereingabe unterstützen?

Hilo sollte auch für Benutzer intuitiv zu verwenden sein, die eine Maus oder ein ähnliches Zeigegerät verwenden. Die integrierten Steuerelemente lassen sich mit der Maus und anderen Zeigegeräten genauso gut wie per Fingereingabe verwenden. Wenn Sie eine App für die Fingereingabe entwerfen, erhalten Sie somit gleichzeitig die entsprechende Funktionalität für Maus und Zeichen-/Eingabestift.

Sie können z. B. die linke Maustaste zum Aufrufen von Befehlen verwenden. Die Windows-Runtime stellt ebenfalls für viele Befehle die entsprechenden Maus- und Tastaturfunktionen bereit. (Beispielsweise können Sie mit der rechten Maustaste die App-Leiste aktivieren, und durch Drehen des Mausrads bei gedrückter STRG-TASTE wird der semantische Zoom gesteuert.)

Mit der PointerPoint-Klasse konnten wir grundlegende Eigenschaften für die Fingereingabe sowie die Eingabe per Maus und Zeichen-/Eingabestift abrufen. Dies ist ein Beispiel für die Verwendung von PointerPoint zum Abrufen der Zeigerposition.

ImageView.xaml.cpp


void Hilo::ImageView::OnImagePointerPressed(Object^ sender, PointerRoutedEventArgs^ e)
{
    m_pointerPressed = true;
    PointerPoint^ point = e->GetCurrentPoint(PhotoGrid);
    m_pointer = point->Position;
    if (point->Properties->IsLeftButtonPressed)
    {
        ImageViewFileInformationPopup->HorizontalOffset = point->Position.X - 200;
        ImageViewFileInformationPopup->VerticalOffset = point->Position.Y - 200;
        ImageViewFileInformationPopup->IsOpen = true;
    }
}


[Oben]

 

 

Anzeigen:
© 2014 Microsoft