Windows 10-Entwicklung - Adaptiver Code

In diesem Kapitel werden wir die Übernahme Ihrer Anwendung auf verschiedene von Windows 10 unterstützte Geräte demonstrieren. Wir haben bereits gelernt, wie Sie Ihre Benutzeroberfläche und alle in UWP-Anwendungen verwendeten Tricks, Techniken und Steuerelemente übernehmen.

Jetzt lernen wir, wie Sie Ihren Code übernehmen, weil

  • Anwendungscodes sind nicht für alle Geräte gleich.

  • APIs, insbesondere für Xbox, sind für mobile Geräte nicht verfügbar. Das gleiche gilt für HoloLens usw.

Adaptive Code kann Ihre Anwendung bedingt beleuchten und Code nur ausführen, wenn er auf einer bestimmten Gerätefamilie und / oder auf einer bestimmten Version der Plattform- / Erweiterungs-APIs ausgeführt wird.

Code schreiben

In Windows 10 können Sie die UWP-Anwendungen in Visual Studio mithilfe von C ++, C #, Visual Basic oder JavaScript implementieren.

  • Mit C # und Visual Basic können Sie XAML für das UI-Design verwenden.

  • Mit C ++ können Sie entweder DirectX anstelle von XAML verwenden.

  • Für JavaScript können Sie HTML für Ihre Präsentationsebene verwenden, bei der es sich um plattformübergreifende Webstandards handelt.

Die Windows Core-APIs werden für alle Geräte auf dieselbe Weise ausgeführt, die die meisten Funktionen enthalten, die Sie für Ihren Code und Ihre Benutzeroberfläche benötigen. Für den Code und die Benutzeroberfläche, die auf bestimmte Gerätefamilien zugeschnitten sind, müssen Sie jedoch den adaptiven Code und die adaptive Benutzeroberfläche verwenden.

Calling an API that is NOT implemented by the target device family −

Die Benutzeroberfläche lässt sich leicht an verschiedene Bildschirme anpassen, aber verschiedene Gerätefamilien haben nicht nur unterschiedliche Bildschirmgrößen, sondern auch viel mehr.

  • Beispielsweise verfügen die Mobiltelefone über einige Hardwaretasten wie Zurück und Kamera, die auf anderen Geräten wie dem PC möglicherweise nicht verfügbar sind.

  • Standardmäßig enthalten die Kern-APIs den größten Teil der Funktionalität, die für alle Geräte funktioniert. Die gerätespezifische Funktionalität kann jedoch verwendet werden, indem auf die Erweiterungs-SDKs in Ihren UWP-Anwendungen wie bei externen Assemblys verwiesen wird.

Führen Sie die folgenden Schritte aus, um ein bestimmtes Erweiterungs-SDK hinzuzufügen, das in Ihrer Anwendung benötigt wird.

  • Klicken Sie mit der rechten Maustaste auf References.

  • Wählen “Add References..”. Der folgende Dialog wird geöffnet.

  • Das Hinzufügen einer Erweiterung ist so einfach wie das Hinzufügen einer Projektreferenz.

  • Jetzt können Sie ein beliebiges Erweiterungs-SDK aus der Liste hinzufügen, das Desktop-Erweiterung, IoT-Erweiterung und mobile Erweiterung usw. enthält.

Desktop- und Mobile-Erweiterungen sind die beiden am häufigsten verwendeten Plattform-Erweiterungs-SDKs. Die Mobile-Erweiterung aktiviert beispielsweise die APIs, die zur Verwendung der Hardware-Kamerataste erforderlich sind.

Sie können die Gerätefunktionen mithilfe von überprüfen Windows.Foundation.Metadata.ApiInformationKlassenmethode, die eine boolesche Ausgabe zurückgibt, wenn der Typ auf dem aktuellen Gerät unterstützt wird. Sie können beispielsweise Ihre Windows-App aktivieren, um die Schaltfläche Kamera mit dem folgenden Code zu verwenden:

bool isHardwareButtonsAPIPresent = 
   Windows.Foundation.Metadata.ApiInformation.
   IsTypePresent("Windows.Phone.UI.Inpu t.HardwareButtons");  
		
if (isHardwareButtonsAPIPresent) { 
   Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed; 
}

Der Tastencode der Telefonkamera wird nur ausgeführt, wenn das Mobile Extension SDK auf dem Gerät aktiviert ist. In ähnlicher Weise können Sie mithilfe der aktuellen API-Version auch nach bestimmten Ereignissen, Methoden oder Eigenschaften suchenIsEventPresent, IsMethodPresent, IsPropertyPresent, Anstatt von IsTypePresent Wie nachfolgend dargestellt.

bool isHardwareButtons_CameraPressedAPIPresent = 
   Windows.Foundation.Metadata.ApiInformation.IsEventPresent 
   ("Windows.Phone.UI.Input.HardwareButtons", "CameraPressed");

Win32-APIs im UWP

Eine UWP-Anwendung (Universal Widows Platform) oder eine Windows Runtime-Komponente, die in C ++ / CX geschrieben sind, können auf Win32-APIs zugreifen, die jetzt auch Teil von UWP sind. Alle Windows 10-Gerätefamilien können Win32-APIs implementieren, indem Sie Ihre Anwendung mit verknüpfenWindowsapp.lib.

Windowsapp.libist eine "Umbrella" -Bibliothek, die die Exporte für die UWP-APIs bereitstellt. Verknüpfen mitWindowsapp.lib wird zu Ihrer App Abhängigkeiten hinzufügen dlls die auf allen Windows 10-Gerätefamilien vorhanden sind.

Schauen wir uns ein einfaches Beispiel an, in dem die Anwendung sowohl auf den Desktop als auch auf das Telefon abzielt. Wenn die Anwendung auf dem Desktop ausgeführt wird, wird daher nicht die Statusleiste angezeigt. Wenn dieselbe Anwendung jedoch auf dem Telefon ausgeführt wird, wird die Statusleiste angezeigt.

Unten ist der XAML-Code angegeben, in dem verschiedene Steuerelemente hinzugefügt werden.

<Page 
   x:Class = "UWPAdoptiveCode.MainPage" 
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:local = "using:UWPAdoptiveCode" 
   xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" 
   mc:Ignorable = "d">  

   <Page.Background> 
      <SolidColorBrush Color = "Green"/> 
   </Page.Background>
	
   <Page.BottomAppBar> 
      <CommandBar x:Name = "commandBar" > 
         <AppBarButton Icon = "Accept" Label = "appbarbutton"/> 
         <AppBarButton Icon = "Cancel" Label = "appbarbutton"/> 
      </CommandBar> 
   </Page.BottomAppBar>
	
   <Grid Background = "AliceBlue"> 
	
      <VisualStateManager.VisualStateGroups> 
		
         <VisualStateGroup> 
			
            <VisualState> 
               <VisualState.StateTriggers> 
                  <local:DeviceFamilyTrigger DeviceFamily = "Desktop" /> 
               </VisualState.StateTriggers> 
					
               <VisualState.Setters> 
                  <Setter Target = "StatusBarControls.Visibility" 
                     Value = "Collapsed"/> 
               </VisualState.Setters>  
					
            </VisualState> 
				
         </VisualStateGroup> 
			
      </VisualStateManager.VisualStateGroups> 
		
      <StackPanel HorizontalAlignment = "Left" Margin = "75,164,0,0"
         VerticalAlignment = "Top" > 
			
         <RadioButton x:Name = "ShowAppBarRadioButton" Content = "Show AppBar"
            HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch"
            IsChecked = "True" Checked = "RadioButton_Checked"/>
				
         <RadioButton x:Name = "ShowOpaqueAppBarRadioButton" 
            Content = "Show Transparent AppBar" HorizontalAlignment = "Stretch"
            VerticalAlignment = "Stretch" Checked = "RadioButton_Checked"/> 
				
         <RadioButton x:Name = "HideAppBarRadioButton" Content = "Hide AppBar"
            HorizontalAlignment = "Stretch" VerticalAlignment = "Stretch" 
            Checked = "RadioButton_Checked"/>
				
      </StackPanel> 
		
      <StackPanel x:Name = "StatusBarControls" Orientation = "Vertical" 
         Margin = "75,350,0,0" Visibility = "Visible">
			
         <CheckBox x:Name = "StatusBarBackgroundCheckBox" 
            Content = "Set StatusBar Background"
            Checked = "StatusBarBackgroundCheckBox_Checked" 
            Unchecked = "StatusBarBackgroundCheckBox_Unchecked"/>
				
         <CheckBox x:Name = "StatusBarHiddenCheckBox" 
            Content = "Set StatusBar Hidden" Checked = "StatusBarHiddenCheckBox_Checked"
            Unchecked = "StatusBarHiddenCheckBox_Unchecked"/> 
				
      </StackPanel> 
		
   </Grid> 
	
</Page>

Im Folgenden ist die C # -Implementierung für verschiedene Ereignisse angegeben.

using Windows.UI; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls;  

// The Blank Page item template is documented at
   http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409  

namespace UWPAdoptiveCode { 
   /// <summary> 
      /// An empty page that can be used on its own or navigated to within a Frame. 
   /// </summary> 
	
   public sealed partial class MainPage : Page { 
     
      private Color? DefaultTitleBarButtonsBGColor; 
      private Color? DefaultTitleBarBGColor;
		
      public MainPage() {
         this.InitializeComponent();
			
         //Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().
            VisibleBoundsCh anged += MainPage_VisibleBoundsChanged;
				
         var viewTitleBar = Windows.UI.ViewManagement.ApplicationView.
            GetForCurrentView().TitleBar; 
				
         DefaultTitleBarBGColor = viewTitleBar.BackgroundColor; 
         DefaultTitleBarButtonsBGColor = viewTitleBar.ButtonBackgroundColor; 
      } 
		
      private void RadioButton_Checked(object sender, RoutedEventArgs e) {
        
         // Bottom AppBar shows on Desktop and Mobile 
         if (ShowAppBarRadioButton != null) {
			  
            if (ShowAppBarRadioButton.IsChecked.HasValue &&
               (ShowAppBarRadioButton.IsChecked.Value == true)) {
                 commandBar.Visibility = Windows.UI.Xaml.Visibility.Visible; 
                 commandBar.Opacity = 1; 
            } else {
               commandBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed; 
            } 
         } 
			
         if (ShowOpaqueAppBarRadioButton != null) {
             
            if (ShowOpaqueAppBarRadioButton.IsChecked.HasValue &&
               (ShowOpaqueAppBarRadioButton.IsChecked.Value == true)){ 
                  commandBar.Visibility = Windows.UI.Xaml.Visibility.Visible; 
                  commandBar.Background.Opacity = 0; 
            } else{ 
               commandBar.Background.Opacity = 1; 
            } 
         } 
			
      } 
		
      private void StatusBarHiddenCheckBox_Checked(object sender, RoutedEventArgs e){
        
         // StatusBar is Mobile only 
         if (Windows.Foundation.Metadata.ApiInformation.
            IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ 
               var ignore = Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync(); 
         } 
      } 
		
      private void StatusBarHiddenCheckBox_Unchecked(object sender, RoutedEventArgs e){
	  
         // StatusBar is Mobile only 
         if (Windows.Foundation.Metadata.ApiInformation.
            IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){
               var ignore = Windows.UI.ViewManagement.StatusBar.GetForCurrentView().ShowAsync(); 
         } 
      }  
		
      private void StatusBarBackgroundCheckBox_Checked(object sender, RoutedEventArgs e){
       
         // StatusBar is Mobile only 
         if (Windows.Foundation.Metadata.ApiInformation.
            IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){ 
				
               Windows.UI.ViewManagement.StatusBar.GetForCurrentView().
                  BackgroundColor = Windows.UI.Colors.Blue; 
					
               Windows.UI.ViewManagement.StatusBar.GetForCurrentView().
                   BackgroundOpacity = 1; 
         } 
      }  
		
      private void StatusBarBackgroundCheckBox_Unchecked(object sender, RoutedEventArgs e){
         
         // StatusBar is Mobile only 
         if (Windows.Foundation.Metadata.ApiInformation.
            IsTypePresent("Windows.UI.ViewManag ement.StatusBar")){
               Windows.UI.ViewManagement.StatusBar.GetForCurrentView().
                  BackgroundOpacity = 0; 
         } 
      } 
		
   } 
	
   public class DeviceFamilyTrigger : StateTriggerBase{
    
      //private variables 
      private string _deviceFamily;
	  
      //Public property 
      public string DeviceFamily {
         
         get {
            return _deviceFamily; 
         } 
         set{
            _deviceFamily = value; 
            var qualifiers = Windows.ApplicationModel.Resources.Core.ResourceContext.
               GetForCurrentView().Qua lifierValues; 
					
            if (qualifiers.ContainsKey("DeviceFamily")) 
               SetActive(qualifiers["DeviceFamily"] == _deviceFamily); 
            else 
               SetActive(false); 
         } 
      } 
   } 
}

Wenn der oben angegebene Code kompiliert und auf einem Mobiltelefon ausgeführt wird, wird das folgende Fenster angezeigt.

Sie können die Hintergrundfarbe der Statusleiste mit dem Kontrollkästchen wie im Bild gezeigt ändern.

Sie können auch die Statusleiste ausblenden.

Wenn Sie jetzt dieselbe Anwendung auf einem Desktop-Gerät ausführen, wird das folgende Fenster angezeigt, in dem die Statusleiste und die für die Statusleiste spezifischen Kontrollkästchen nicht sichtbar sind.