Samouczek: obsługa Surface Dial (i innych urządzeń kołowych) w aplikacji Windows

Obraz Surface Dial z Surface Studio
Surface Dial z Surface Studio i Surface Pen.

W tym samouczku przedstawiono, jak dostosować doświadczenia interakcji użytkownika obsługiwane przez urządzenia kołowe, takie jak Surface Dial. Używamy fragmentów kodu z przykładowej aplikacji, którą można pobrać z GitHub (zobacz Przykład kodu), aby zademonstrować różne funkcje i skojarzone RadialController interfejsy API omówione w każdym kroku.

Koncentrujemy się na następujących kwestiach:

  • Określanie, które wbudowane narzędzia są wyświetlane w menu RadialController
  • Dodawanie niestandardowego narzędzia do menu
  • Kontrolowanie sprzężenia zwrotnego haptycznego
  • Dostosowywanie interakcji kliknięcia
  • Dostosowywanie interakcji rotacji

Aby uzyskać więcej informacji na temat implementowania tych i innych funkcji, zobacz interakcje Surface Dial w aplikacjach Windows.

Introduction

Surface Dial to pomocnicze urządzenie wejściowe, które pomaga użytkownikom być bardziej wydajne w przypadku użycia razem z podstawowym urządzeniem wejściowym, takim jak pióro, dotyk lub mysz. Jako pomocnicze urządzenie wejściowe, Dial jest zwykle używany z niedominującą ręką, aby zapewnić dostęp zarówno do poleceń systemowych, jak i do innych, bardziej kontekstowych narzędzi i funkcji.

Tarcza obsługuje trzy podstawowe gesty:

  • Naciśnij i przytrzymaj, aby wyświetlić wbudowane menu poleceń.
  • Obróć, aby wyróżnić element menu (jeśli menu jest aktywne) lub zmodyfikować bieżącą akcję w aplikacji (jeśli menu nie jest aktywne).
  • Kliknij, aby wybrać wyróżniony element menu (jeśli menu jest aktywne) lub wywołać polecenie w aplikacji (jeśli menu nie jest aktywne).

Wymagania wstępne

Konfigurowanie urządzeń

  1. Upewnij się, że urządzenie Windows jest włączone.
  2. Przejdź do pozycji Start, wybierz pozycję Ustawienia>Urządzenia>Bluetooth i inne urządzenia, a następnie włącz funkcję Bluetooth .
  3. Usuń dół Surface Dial, aby otworzyć przedział baterii i upewnij się, że w środku znajdują się dwie baterie AAA.
  4. Jeśli karta baterii znajduje się na uboczu tarczy, usuń ją.
  5. Naciśnij i przytrzymaj mały, wpuszczony przycisk obok baterii, aż światło Bluetooth zacznie migać.
  6. Wróć do urządzenia Windows i wybierz pozycję Dodaj połączenie Bluetooth lub inne urządzenie.
  7. W oknie dialogowym Dodaj urządzenie wybierz pozycję Bluetooth>Surface Dial. Surface Dial powinien teraz połączyć się i zostać dodany do listy urządzeń w Mouse, klawiatura i pióro na stronie ustawień Bluetooth i inne urządzenia.
  8. Przetestuj pokrętło, naciskając i przytrzymując je przez kilka sekund, aby wyświetlić wbudowane menu.
  9. Jeśli menu nie jest wyświetlane na ekranie (pokrętło powinno również wibrować), wróć do ustawień Bluetooth, usuń urządzenie i spróbuj połączyć się z urządzeniem ponownie.

Uwaga / Notatka

Urządzenia kołowe można skonfigurować za pomocą ustawień koła :

  1. W menu Start wybierz pozycję Ustawienia.
  2. Wybierz Urządzenia>Koło.
    Ekran ustawień koła

Teraz jesteś gotowy, aby rozpocząć ten samouczek.

Przykładowy kod

W tym samouczku korzystamy z przykładowej aplikacji do zademonstrowania omówionych pojęć i funkcjonalności.

Pobierz ten przykład Visual Studio i kod źródłowy z GitHub pod adresem windows-appsample-get-started-radialcontroller sample:

  1. Wybierz zielony przycisk Klonuj lub pobierz .
    Klonowanie repozytorium
  2. Jeśli masz konto GitHub, możesz sklonować repozytorium na komputer lokalny, wybierając pozycję Otwórz w Visual Studio.
  3. Jeśli nie masz konta GitHub lub chcesz po prostu uzyskać lokalną kopię projektu, wybierz Pobierz plik ZIP (musisz regularnie sprawdzać, aby pobrać najnowsze aktualizacje).

Ważna

Większość kodu w przykładzie jest zakomentowana. Podczas wykonywania poszczególnych kroków w tym temacie zostaniesz poproszony o odkomentowanie różnych sekcji kodu. W Visual Studio wyróżnij wiersze kodu, a następnie naciśnij CTRL-K, a następnie naciśnij klawisze CTRL-U.

Składniki obsługujące funkcje koła

Te obiekty zapewniają większość środowiska urządzenia kołowego dla aplikacji Windows.

Składnik Opis
klasa RadialController i powiązane Reprezentuje urządzenie do wprowadzania danych z wykorzystaniem koła lub akcesorium, takie jak Surface Dial.
IRadialControllerConfigurationInterop / IRadialControllerInterop
Nie omówiono tutaj tej funkcji, aby uzyskać więcej informacji, zobacz przykład Windows desktop.
Umożliwia współdziałanie z aplikacją Windows.

Krok 1. Uruchamianie przykładu

Po pobraniu przykładowej aplikacji RadialController sprawdź, czy działa:

  1. Otwórz przykładowy projekt w Visual Studio .
  2. Ustaw listę rozwijaną Platformy rozwiązań na opcję inną niż Arm.
  3. Naciśnij F5, aby skompilować, wdrożyć i uruchomić.

Uwaga / Notatka

Alternatywnie możesz wybrać Debug>Rozpocznij debugowanie element menu lub wybrać przycisk Maszyna lokalna Uruchom pokazany poniżej: przycisk Buduj projekt Visual Studio

Zostanie otwarte okno aplikacji, a po pojawieniu się ekranu startowego przez kilka sekund, zobaczysz ten ekran główny.

Pusta aplikacja

Teraz mamy podstawową aplikację Windows, która będzie używana w pozostałej części tego samouczka. W poniższych krokach dodamy naszą funkcję RadialController .

Krok 2. Podstawowa funkcja RadialController

Po uruchomieniu aplikacji i na pierwszym planie naciśnij i przytrzymaj Surface Dial, aby wyświetlić menu RadialController.

Nie wykonaliśmy jeszcze żadnych dostosowań dla naszej aplikacji, więc menu zawiera domyślny zestaw narzędzi kontekstowych.

Te obrazy przedstawiają dwie odmiany menu domyślnego. (Istnieje wiele innych, w tym tylko podstawowe narzędzia systemowe, gdy Windows Desktop jest aktywny, a żadne aplikacje nie znajdują się na pierwszym planie, dodatkowe narzędzia pisma odręcznego, gdy jest obecny pasek narzędzi inkToolbar i narzędzia mapowania podczas korzystania z aplikacji Maps.

Menu RadialController (domyślne) Menu RadialController (domyślne z odtwarzaniem multimediów)
Domyślne menu RadialController Domyślne menu RadialController z muzyką

Teraz zaczniemy od pewnych podstawowych dostosowań.

Krok 3. Dodawanie kontrolek dla sterowania kółkiem

Najpierw dodajmy interfejs użytkownika dla naszej aplikacji:

  1. Otwórz plik MainPage_Basic.xaml.

  2. Znajdź kod oznaczony tytułem tego kroku ("<-- Krok 3: Dodawanie kontrolek dla danych wejściowych koła -->").

  3. Usuń komentarz z następujących wierszy.

    <Button x:Name="InitializeSampleButton" 
            HorizontalAlignment="Center" 
            Margin="10" 
            Content="Initialize sample" />
    <ToggleButton x:Name="AddRemoveToggleButton"
                    HorizontalAlignment="Center" 
                    Margin="10" 
                    Content="Remove Item"
                    IsChecked="True" 
                    IsEnabled="False"/>
    <Button x:Name="ResetControllerButton" 
            HorizontalAlignment="Center" 
            Margin="10" 
            Content="Reset RadialController menu" 
            IsEnabled="False"/>
    <Slider x:Name="RotationSlider" Minimum="0" Maximum="10"
            Width="300"
            HorizontalAlignment="Center"/>
    <TextBlock Text="{Binding ElementName=RotationSlider, Mode=OneWay, Path=Value}"
                Margin="0,0,0,20"
                HorizontalAlignment="Center"/>
    <ToggleSwitch x:Name="ClickToggle"
                    MinWidth="0" 
                    Margin="0,0,0,20"
                    HorizontalAlignment="center"/>
    

W tym momencie włączony jest tylko przycisk Inicjuj przykład, suwak i przełącznik. Inne przyciski są używane w kolejnych krokach, aby dodać i usunąć elementy menu RadialController , które zapewniają dostęp do suwaka i przełącznika.

Podstawowy przykładowy interfejs użytkownika aplikacji

Krok 4. Dostosowywanie podstawowego menu RadialController

Teraz dodajmy kod wymagany do włączenia dostępu RadialController do naszych kontrolek.

  1. Otwórz plik MainPage_Basic.xaml.cs.
  2. Znajdź kod oznaczony tytułem tego kroku ("// Krok 4: Dostosowywanie menu Basic RadialController").
  3. Usuń komentarz z następujących wierszy:
    • Windows.UI.Input i Windows.Storage.Streams są używane do zapewnienia funkcjonalności w kolejnych krokach.

      // Using directives for RadialController functionality.
      using Windows.UI.Input;
      
    • Te obiekty globalne (RadialController, RadialControllerConfiguration, RadialControllerMenuItem) są używane w całej naszej aplikacji.

      private RadialController radialController;
      private RadialControllerConfiguration radialControllerConfig;
      private RadialControllerMenuItem radialControllerMenuItem;
      
    • W tym miejscu określamy procedurę obsługi kliknięć dla przycisku, który włącza nasze kontrolki i inicjuje nasz niestandardowy element menu RadialController .

      InitializeSampleButton.Click += (sender, args) =>
      { InitializeSample(sender, args); };
      
    • Następnie zainicjujemy obiekt RadialController i skonfigurujemy programy obsługi dla zdarzeń RotationChanged i ButtonClicked .

      // Set up the app UI and RadialController.
      private void InitializeSample(object sender, RoutedEventArgs e)
      {
          ResetControllerButton.IsEnabled = true;
          AddRemoveToggleButton.IsEnabled = true;
      
          ResetControllerButton.Click += (resetsender, args) =>
          { ResetController(resetsender, args); };
          AddRemoveToggleButton.Click += (togglesender, args) =>
          { AddRemoveItem(togglesender, args); };
      
          InitializeController(sender, e);
      }
      
    • W tym miejscu zainicjujemy nasz niestandardowy element menu RadialController. Użyjemy polecenia CreateForCurrentView , aby uzyskać odwołanie do naszego obiektu RadialController , ustawiamy czułość rotacji na wartość "1" przy użyciu właściwości RotationResolutionInDegrees , a następnie tworzymy nasze elementy menu RadialControllerMenuItem za pomocą polecenia CreateFromFontGlyph, dodamy element menu do kolekcji elementów menu RadialController , a na koniec użyjemy polecenia SetDefaultMenuItems , aby wyczyścić domyślne elementy menu i pozostawić tylko nasze niestandardowe narzędzie.

      // Configure RadialController menu and custom tool.
      private void InitializeController(object sender, RoutedEventArgs args)
      {
          // Create a reference to the RadialController.
          radialController = RadialController.CreateForCurrentView();
          // Set rotation resolution to 1 degree of sensitivity.
          radialController.RotationResolutionInDegrees = 1;
      
          // Create the custom menu items.
          // Here, we use a font glyph for our custom tool.
          radialControllerMenuItem =
              RadialControllerMenuItem.CreateFromFontGlyph("SampleTool", "\xE1E3", "Segoe MDL2 Assets");
      
          // Add the item to the RadialController menu.
          radialController.Menu.Items.Add(radialControllerMenuItem);
      
          // Remove built-in tools to declutter the menu.
          // NOTE: The Surface Dial menu must have at least one menu item. 
          // If all built-in tools are removed before you add a custom 
          // tool, the default tools are restored and your tool is appended 
          // to the default collection.
          radialControllerConfig =
              RadialControllerConfiguration.GetForCurrentView();
          radialControllerConfig.SetDefaultMenuItems(
              new RadialControllerSystemMenuItemKind[] { });
      
          // Declare input handlers for the RadialController.
          // NOTE: These events are only fired when a custom tool is active.
          radialController.ButtonClicked += (clicksender, clickargs) =>
          { RadialController_ButtonClicked(clicksender, clickargs); };
          radialController.RotationChanged += (rotationsender, rotationargs) =>
          { RadialController_RotationChanged(rotationsender, rotationargs); };
      }
      
      // Connect wheel device rotation to slider control.
      private void RadialController_RotationChanged(
          object sender, RadialControllerRotationChangedEventArgs args)
      {
          if (RotationSlider.Value + args.RotationDeltaInDegrees >= RotationSlider.Maximum)
          {
              RotationSlider.Value = RotationSlider.Maximum;
          }
          else if (RotationSlider.Value + args.RotationDeltaInDegrees < RotationSlider.Minimum)
          {
              RotationSlider.Value = RotationSlider.Minimum;
          }
          else
          {
              RotationSlider.Value += args.RotationDeltaInDegrees;
          }
      }
      
      // Connect wheel device click to toggle switch control.
      private void RadialController_ButtonClicked(
          object sender, RadialControllerButtonClickedEventArgs args)
      {
          ClickToggle.IsOn = !ClickToggle.IsOn;
      }
      
  4. Teraz ponownie uruchom aplikację.
  5. Wybierz przycisk Zainicjuj kontroler promieniowy .
  6. W aplikacji na pierwszym planie naciśnij i przytrzymaj Surface Dial, aby wyświetlić menu. Zwróć uwagę, że wszystkie narzędzia domyślne zostały usunięte (przy użyciu metody RadialControllerConfiguration.SetDefaultMenuItems ), pozostawiając tylko narzędzie niestandardowe. Oto menu z naszym niestandardowym narzędziem.
Menu RadialController (niestandardowe)
Niestandardowe menu RadialController
  1. Wybierz narzędzie niestandardowe i wypróbuj teraz interakcje obsługiwane za pomocą Surface Dial:
    • Akcja obracania przesuwa suwak.
    • Kliknięcie powoduje włączenie lub wyłączenie przełącznika.

Ok, podłączmy te przyciski.

Krok 5: Konfigurowanie menu w trakcie działania

W tym kroku podłączymy elementy menu Dodaj/Usuń element i Resetuj menu RadialController, aby pokazać, jak można dynamicznie dostosować menu.

  1. Otwórz plik MainPage_Basic.xaml.cs.

  2. Znajdź kod oznaczony tytułem tego kroku ("// Krok 5: Konfigurowanie menu w czasie wykonywania").

  3. Odkomentuj kod w poniższych metodach i ponownie uruchom aplikację, ale nie wybieraj żadnych przycisków (zostaw to na kolejny krok).

    // Add or remove the custom tool.
    private void AddRemoveItem(object sender, RoutedEventArgs args)
    {
        if (AddRemoveToggleButton?.IsChecked == true)
        {
            AddRemoveToggleButton.Content = "Remove item";
            if (!radialController.Menu.Items.Contains(radialControllerMenuItem))
            {
                radialController.Menu.Items.Add(radialControllerMenuItem);
            }
        }
        else if (AddRemoveToggleButton?.IsChecked == false)
        {
            AddRemoveToggleButton.Content = "Add item";
            if (radialController.Menu.Items.Contains(radialControllerMenuItem))
            {
                radialController.Menu.Items.Remove(radialControllerMenuItem);
                // Attempts to select and activate the previously selected tool.
                // NOTE: Does not differentiate between built-in and custom tools.
                radialController.Menu.TrySelectPreviouslySelectedMenuItem();
            }
        }
    }
    
    // Reset the RadialController to initial state.
    private void ResetController(object sender, RoutedEventArgs arg)
    {
        if (!radialController.Menu.Items.Contains(radialControllerMenuItem))
        {
            radialController.Menu.Items.Add(radialControllerMenuItem);
        }
        AddRemoveToggleButton.Content = "Remove item";
        AddRemoveToggleButton.IsChecked = true;
        radialControllerConfig.SetDefaultMenuItems(
            new RadialControllerSystemMenuItemKind[] { });
    }
    
  4. Wybierz przycisk Usuń element, a następnie naciśnij i przytrzymaj pokrętło, aby ponownie otworzyć menu.

    Zwróć uwagę, że menu zawiera teraz domyślną kolekcję narzędzi. Pamiętaj, że w kroku 3 podczas konfigurowania menu niestandardowego usunęliśmy wszystkie narzędzia domyślne i dodaliśmy tylko nasze narzędzie niestandardowe. Zauważyliśmy również, że po ustawieniu menu na pustą kolekcję zostaną przywrócone domyślne elementy bieżącego kontekstu. (Dodaliśmy nasze narzędzie niestandardowe przed usunięciem narzędzi domyślnych).

  5. Wybierz przycisk Dodaj element , a następnie naciśnij i przytrzymaj Dial.

    Zwróć uwagę, że menu zawiera teraz zarówno domyślną kolekcję narzędzi, jak i nasze narzędzie niestandardowe.

  6. Wybierz przycisk menu Resetuj kontrolkę RadialController, a następnie naciśnij i przytrzymaj pokrętło.

    Zwróć uwagę, że menu powraca do pierwotnego stanu.

Krok 6. Dostosowywanie haptyki urządzenia

Surface Dial i inne urządzenia kołowe mogą zapewniać użytkownikom informację zwrotną haptyczną, odpowiadającą obecnej interakcji (czyli kliknięciu lub obrotowi).

W tym kroku pokażemy, jak dostosować informację zwrotną haptyczną, kojarząc nasze kontrolki suwaka i przełącznika oraz używając ich do dynamicznego określania zachowania informacji zwrotnej haptycznej. W tym przykładzie przełącznik musi być ustawiony na włączony, aby włączyć informację zwrotną, a wartość suwaka określa, jak często jest powtarzana informacja zwrotna kliknięcia.

Uwaga / Notatka

Informacja zwrotna haptyczna może być wyłączona przez użytkownika na stronie Ustawienia>Urządzenia>Kierownica.

  1. Otwórz plik App.xaml.cs.

  2. Znajdź kod oznaczony tytułem tego kroku ("Krok 6: Dostosowywanie haptyki urządzenia").

  3. Zakomentuj pierwszy i trzeci wiersz ("MainPage_Basic" i "MainPage") i odkomentuj drugi ("MainPage_Haptics").

    rootFrame.Navigate(typeof(MainPage_Basic), e.Arguments);
    rootFrame.Navigate(typeof(MainPage_Haptics), e.Arguments);
    rootFrame.Navigate(typeof(MainPage), e.Arguments);
    
  4. Otwórz plik MainPage_Haptics.xaml.

  5. Znajdź kod oznaczony tytułem tego kroku ("<-- Krok 6: Dostosowywanie haptyki urządzenia -->").

  6. Usuń komentarz z następujących wierszy. (Ten kod interfejsu użytkownika po prostu wskazuje, jakie funkcje haptyczne są obsługiwane przez bieżące urządzenie).

    <StackPanel x:Name="HapticsStack" 
                Orientation="Vertical" 
                HorizontalAlignment="Center" 
                BorderBrush="Gray" 
                BorderThickness="1">
        <TextBlock Padding="10" 
                    Text="Supported haptics properties:" />
        <CheckBox x:Name="CBDefault" 
                    Content="Default" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsChecked="True" />
        <CheckBox x:Name="CBIntensity" 
                    Content="Intensity" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
        <CheckBox x:Name="CBPlayCount" 
                    Content="Play count" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
        <CheckBox x:Name="CBPlayDuration" 
                    Content="Play duration" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
        <CheckBox x:Name="CBReplayPauseInterval" 
                    Content="Replay/pause interval" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
        <CheckBox x:Name="CBBuzzContinuous" 
                    Content="Buzz continuous" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
        <CheckBox x:Name="CBClick" 
                    Content="Click" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
        <CheckBox x:Name="CBPress" 
                    Content="Press" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
        <CheckBox x:Name="CBRelease" 
                    Content="Release" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
        <CheckBox x:Name="CBRumbleContinuous" 
                    Content="Rumble continuous" 
                    Padding="10" 
                    IsEnabled="False" 
                    IsThreeState="True" 
                    IsChecked="{x:Null}" />
    </StackPanel>
    
  7. Otwieranie pliku MainPage_Haptics.xaml.cs

  8. Znajdź kod oznaczony tytułem tego kroku ("Krok 6: dostosowywanie haptyczne")

  9. Usuń komentarz z następujących wierszy:

    • Windows.Devices.Haptics odwołanie do typu jest używane do zapewnienia funkcjonalności w kolejnych krokach.

      using Windows.Devices.Haptics;
      
    • W tym miejscu określamy procedurę obsługi dla zdarzenia ControlAcquired , które jest wyzwalane po wybraniu niestandardowego elementu menu RadialController .

      radialController.ControlAcquired += (rc_sender, args) =>
      { RadialController_ControlAcquired(rc_sender, args); };
      
    • Następnie zdefiniujemy program obsługi ControlAcquired , w którym wyłączamy domyślne opinie haptyczne i inicjujemy nasz interfejs użytkownika haptics.

      private void RadialController_ControlAcquired(
          RadialController rc_sender,
          RadialControllerControlAcquiredEventArgs args)
      {
          // Turn off default haptic feedback.
          radialController.UseAutomaticHapticFeedback = false;
      
          SimpleHapticsController hapticsController =
              args.SimpleHapticsController;
      
          // Enumerate haptic support.
          IReadOnlyCollection<SimpleHapticsControllerFeedback> supportedFeedback =
              hapticsController.SupportedFeedback;
      
          foreach (SimpleHapticsControllerFeedback feedback in supportedFeedback)
          {
              if (feedback.Waveform == KnownSimpleHapticsControllerWaveforms.BuzzContinuous)
              {
                  CBBuzzContinuous.IsEnabled = true;
                  CBBuzzContinuous.IsChecked = true;
              }
              else if (feedback.Waveform == KnownSimpleHapticsControllerWaveforms.Click)
              {
                  CBClick.IsEnabled = true;
                  CBClick.IsChecked = true;
              }
              else if (feedback.Waveform == KnownSimpleHapticsControllerWaveforms.Press)
              {
                  CBPress.IsEnabled = true;
                  CBPress.IsChecked = true;
              }
              else if (feedback.Waveform == KnownSimpleHapticsControllerWaveforms.Release)
              {
                  CBRelease.IsEnabled = true;
                  CBRelease.IsChecked = true;
              }
              else if (feedback.Waveform == KnownSimpleHapticsControllerWaveforms.RumbleContinuous)
              {
                  CBRumbleContinuous.IsEnabled = true;
                  CBRumbleContinuous.IsChecked = true;
              }
          }
      
          if (hapticsController?.IsIntensitySupported == true)
          {
              CBIntensity.IsEnabled = true;
              CBIntensity.IsChecked = true;
          }
          if (hapticsController?.IsPlayCountSupported == true)
          {
              CBPlayCount.IsEnabled = true;
              CBPlayCount.IsChecked = true;
          }
          if (hapticsController?.IsPlayDurationSupported == true)
          {
              CBPlayDuration.IsEnabled = true;
              CBPlayDuration.IsChecked = true;
          }
          if (hapticsController?.IsReplayPauseIntervalSupported == true)
          {
              CBReplayPauseInterval.IsEnabled = true;
              CBReplayPauseInterval.IsChecked = true;
          }
      }
      
    • W naszych programach obsługi zdarzeń RotationChanged i ButtonClicked łączymy odpowiednie suwaki i kontrolki przycisków przełączających z naszymi niestandardowymi haptykami.

      // Connect wheel device rotation to slider control.
      private void RadialController_RotationChanged(
          object sender, RadialControllerRotationChangedEventArgs args)
      {
          ...
          if (ClickToggle.IsOn && 
              (RotationSlider.Value > RotationSlider.Minimum) && 
              (RotationSlider.Value < RotationSlider.Maximum))
          {
              SimpleHapticsControllerFeedback waveform = 
                  FindWaveform(args.SimpleHapticsController, 
                  KnownSimpleHapticsControllerWaveforms.BuzzContinuous);
              if (waveform != null)
              {
                  args.SimpleHapticsController.SendHapticFeedback(waveform);
              }
          }
      }
      
      private void RadialController_ButtonClicked(
          object sender, RadialControllerButtonClickedEventArgs args)
      {
          ...
      
          if (RotationSlider?.Value > 0)
          {
              SimpleHapticsControllerFeedback waveform = 
                  FindWaveform(args.SimpleHapticsController, 
                  KnownSimpleHapticsControllerWaveforms.Click);
      
              if (waveform != null)
              {
                  args.SimpleHapticsController.SendHapticFeedbackForPlayCount(
                      waveform, 1.0, 
                      (int)RotationSlider.Value, 
                      TimeSpan.Parse("1"));
              }
          }
      }
      
    • Na koniec otrzymujemy żądany Waveform (jeśli jest obsługiwany) dla informacji zwrotnej haptycznej.

      // Get the requested waveform.
      private SimpleHapticsControllerFeedback FindWaveform(
          SimpleHapticsController hapticsController,
          ushort waveform)
      {
          foreach (var hapticInfo in hapticsController.SupportedFeedback)
          {
              if (hapticInfo.Waveform == waveform)
              {
                  return hapticInfo;
              }
          }
          return null;
      }
      

Uruchom aplikację ponownie, aby wypróbować niestandardowe haptyki, zmieniając wartość suwaka i zmieniając stan przełącznika.

Krok 7. Definiowanie interakcji na ekranie dla Surface Studio i podobnych urządzeń

W połączeniu z Surface Studio Surface Dial może zapewnić jeszcze bardziej wyjątkowe doświadczenie użytkownika.

Oprócz opisanego domyślnego działania menu przyciśnięcia i przytrzymania, Surface Dial można także umieścić bezpośrednio na ekranie Surface Studio. Umożliwia to specjalne menu "na ekranie".

Wykrywając zarówno lokalizację kontaktu, jak i granice Surface Dial, system obsługuje okluzję przez urządzenie i wyświetla większą wersję menu, które otacza tarczę. Te same informacje mogą być również używane przez aplikację w celu dostosowania interfejsu użytkownika zarówno do obecności urządzenia, jak i oczekiwanego użycia, na przykład umieszczenia ręki i ramienia użytkownika.

Przykład, który towarzyszy temu samouczkowi, zawiera nieco bardziej złożony przykład, który demonstruje niektóre z tych możliwości.

Aby zobaczyć to w akcji (potrzebujesz Surface Studio):

  1. Pobierz przykład na urządzeniu Surface Studio (z zainstalowanym Visual Studio)

  2. Otwórz przykład w Visual Studio

  3. Otwieranie pliku App.xaml.cs

  4. Znajdź kod oznaczony tytułem tego kroku ("Krok 7: Definiowanie interakcji na ekranie dla Surface Studio i podobnych urządzeń")

  5. Zakomentuj pierwsze i drugie wiersze ("MainPage_Basic" i "MainPage_Haptics") i odkomentuj trzeci ("MainPage")

    rootFrame.Navigate(typeof(MainPage_Basic), e.Arguments);
    rootFrame.Navigate(typeof(MainPage_Haptics), e.Arguments);
    rootFrame.Navigate(typeof(MainPage), e.Arguments);
    
  6. Uruchom aplikację i umieść Surface Dial w każdym z dwóch regionów sterowania, na przemian między nimi.
    Radialny kontroler ekranu

Podsumowanie

Gratulacje, ukończyłeś samouczek Rozpocznij: Wsparcie dla Surface Dial (i innych urządzeń kółkowych) w aplikacji Windows! Pokazaliśmy podstawowy kod wymagany do obsługi urządzenia kołowego w aplikacjach Windows oraz sposób zapewniania niektórych bardziej zaawansowanych środowisk użytkownika obsługiwanych przez interfejsy API RadialController.

Interakcje Surface Dial

Odniesienie do API

Próbki

Przykłady tematów

Dostosowywanie RadialController

Inne przykłady

przykład Coloring Book

Przykłady dla platformy Universal Windows Platform (C# i C++)

Przykład pulpitu Windows