Desarrollo de Windows 10 - Código adaptable

En este capítulo, demostraremos la adopción de su aplicación en diferentes dispositivos compatibles con Windows 10. Ya hemos aprendido sobre la adopción de su interfaz de usuario y todos los trucos, técnicas y controles utilizados en las aplicaciones para UWP.

Ahora, aprenderemos sobre la adopción de su código, porque

  • Los códigos de aplicación no son los mismos en todos los dispositivos.

  • Las API utilizadas, especialmente para Xbox, no estarán disponibles para dispositivos móviles. Lo mismo ocurre con HoloLens, etc.

Adaptive El código puede iluminar su aplicación de forma condicional y ejecutar código solo cuando se ejecuta en una familia de dispositivos específica y / o en una versión particular de la plataforma / extensión API.

Código de escritura

En Windows 10, puede implementar las aplicaciones para UWP en Visual Studio mediante C ++, C #, Visual Basic o JavaScript.

  • Con C # y Visual Basic, puede usar XAML para el diseño de la interfaz de usuario.

  • Con C ++ puedes usar DirectX en lugar de usar XAML.

  • Para JavaScript, puede usar HTML para su capa de presentación, que es un estándar web multiplataforma.

Las API de Windows Core se ejecutan de la misma manera para todos los dispositivos, que contienen la mayor parte de la funcionalidad que necesita para su código y su interfaz de usuario. Sin embargo, para el código y la interfaz de usuario adaptados a familias de dispositivos particulares, es necesario utilizar el código y la interfaz de usuario adaptables.

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

La interfaz de usuario se adapta fácilmente a diferentes pantallas, pero las diferentes familias de dispositivos no solo tienen diferentes tamaños de pantalla, tienen mucho más que eso.

  • Por ejemplo, los teléfonos móviles tienen algunos botones de hardware como Atrás y Cámara, que pueden no estar disponibles en otros dispositivos como PC.

  • De forma predeterminada, las API principales contienen la mayor parte de la funcionalidad, que funciona para todos los dispositivos, pero la funcionalidad específica del dispositivo se puede usar haciendo referencia a los SDK de extensión en sus aplicaciones para UWP al igual que los ensamblados externos.

Para agregar cualquier SDK de extensión en particular, necesario en su aplicación, siga los pasos que se indican a continuación:

  • Haga clic derecho en el References.

  • Seleccione “Add References..”. Se abrirá el siguiente cuadro de diálogo.

  • Agregar una extensión es tan simple como agregar una referencia de proyecto.

  • Ahora puede agregar cualquier SDK de extensión de la lista, que contiene Extensión de escritorio, Extensión de IoT y Extensión móvil, etc.

Las extensiones de escritorio y móviles son los dos SDK de extensión de plataforma más comunes. La extensión Mobile, por ejemplo, habilita las API necesarias para usar el botón de cámara de hardware.

Puede comprobar las capacidades del dispositivo utilizando el Windows.Foundation.Metadata.ApiInformationmétodo de clase, que devuelve una salida booleana si el tipo es compatible con el dispositivo actual. Por ejemplo, puede habilitar su aplicación de Windows para usar el botón Cámara con un código como este:

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

El código del botón teléfono-cámara se ejecutará solo si Mobile Extension SDK está habilitado en el dispositivo. De manera similar, también puede verificar cualquier evento, método o propiedad en particular en la versión actual de la API usandoIsEventPresent, IsMethodPresent, IsPropertyPresent, en vez de IsTypePresent Como se muestra abajo.

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

API de Win32 en la UWP

Una aplicación de Universal Widows Platform (UWP) o un componente de tiempo de ejecución de Windows, que están escritos en C ++ / CX, pueden acceder a las API de Win32, que ahora también forman parte de UWP. Todas las familias de dispositivos de Windows 10 pueden implementar las API de Win32 vinculando su aplicación conWindowsapp.lib.

Windowsapp.libes una biblioteca "paraguas" que proporciona las exportaciones para las API de UWP. Vinculando aWindowsapp.lib agregará a su aplicación dependencias en dlls que están presentes en todas las familias de dispositivos de Windows 10.

Echemos un vistazo a un ejemplo simple en el que la aplicación se dirige tanto al escritorio como al teléfono. Por lo tanto, cuando la aplicación se ejecuta en el escritorio, no mostrará la barra de estado, pero cuando la misma aplicación se ejecuta en el teléfono, mostrará la barra de estado.

A continuación se muestra el código XAML en el que se agregan diferentes controles.

<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>

A continuación se muestra la implementación de C # para diferentes eventos.

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); 
         } 
      } 
   } 
}

Cuando el código anterior se compila y ejecuta en un dispositivo móvil, verá la siguiente ventana.

Puede cambiar el color de fondo de la barra de estado con la casilla de verificación como se muestra en la imagen.

También puede ocultar la barra de estado.

Ahora, cuando ejecute la misma aplicación en un dispositivo de escritorio, verá la siguiente ventana en la que la barra de estado y las casillas de verificación específicas de la barra de estado no están visibles.