Archivo de la etiqueta: Windows Store

Saber si una aplicación de Windows Store es de prueba (trial) o comprada

 

Pues eso… cuando publicas una aplicación "de pago" en Windows Store puedes indicar un periodo de prueba (trial). Saber si la aplicación es aún de prueba o no te permite poder cambiar algunas de las opciones de tu aplicación, si es que realmente quieres hacer esa distinción, si no quieres hacer ninguna distinción puedes dejar de leer esto jejeje.

La forma más simple es hacer una comprobación del valor devuelto por la propiedad IsTrial de la propiedad LicenseInformation que está definida en la clase CurrentApp:
CurrentApp.LicenseInformation.IsTrial

Nota:
Según indica la ayuda de CurrentApp, para poder usarla necesitas tener una cuenta de desarrollador de Windows Store. Si no es así, puedes usar la clase CurrentAppSimulator.

La forma más práctica de usar el valor de esa propiedad es bien almacenándola en una variable o bien usarla para comprobar si, por ejemplo, se deben mostrar ciertas opciones o controles en nuestra app. Por supuesto, si vas a hacer varias comprobaciones en sitios diferentes de tu aplicación, lo mejor es que utilices una variable local (a nivel de la página).

Además, también tienes que tener en cuenta de que mientras tu aplicación se está ejecutando es posible que el usuario la haya comprado, por tanto es interesante por no decir conveniente que tu aplicación se entere de si la app ha cambiado de trial a de pago. Por suerte existe un evento en la clase CurrentApp que te permite saber si esto ocurre. Ese evento es: LicenseChanged.

El evento LicenseChanged se producirá cuando cambie el tipo de licencia de tu aplicación, y en ese método de evento es donde puedes re-asignar el valor de la variable esa que te comentaba antes (la de saber si es trial o no).

 

blog isTrial
Figura 1. Un ejemplo de uso en Visual Basic de IsTrial…

 

Pues nada, esto es todo… solo decirte (y recomendarte) que le eches un vistazo a la ayuda sobre la clase CurrentApp porque ahí tienes más cosillas interesantes que puedes hacer con tu aplicación, pero siempre relacionadas con la Tienda de Windows y la compra de la app, incluso desde dentro de la propia aplicación (in-app purchase).

Este enlace te llevará a un ejemplo del Dev Center de Microsoft con ejemplos para esto que te he comentado y además de realizar compras desde la aplicación (in-app purchase).
Si tu lenguaje preferido es Visual Basic .NET, decirte que no hay código de ejemplo para VB, solo para C#, JavaScript y C++, pero bueno…
Trial app and in-app purchase sample.

 

Esto es válido para las aplicaciones de la Tienda de Windows de Windows 8 y superior; además de las aplicaciones para Windows Phone 8 y superior.

Espero que te sea de utilidad.

 

Nos vemos.
Guillermo

Cómo usar el FileOpenPicker para seleccionar ficheros en las apps de Windows Store

 

Pues eso… ahora le toca el turno al FileOpenPicker el "seleccionador" de ficheros en las aplicaciones de la Tienda de Windows.

En las aplicaciones para la Tienda de Windows (Windows Store) esta es la única forma (que yo conozco) de acceder a una carpeta local (o de la red o de un disco extraíble o de un sistema de almacenamiento como Skydrive) y seleccionar un fichero.

Aunque antes hay que indicarle a la aplicación de que queremos acceder a esos sitios, para ello tendremos que abrir el fichero de manifiesto de la aplicación (Package.appxmanifest) y en la ficha Capabilities (ver figura 1) indicar que queremos utilizar el Private Networks y Removable Storage (por si queremos acceder a un disco externo/conectado por USB).

 

FileOpenPicker 02
Figura 1. Indicar las "Capabilities" de la aplicación

 

Lo siguiente que tenemos que hacer es indicar en la ficha Declarations que queremos usar el File Open Picker.

 

FileOpenPicker 03
Figura 2. En Declarations indicamos que queremos usar el File Open Picker

 

Tal como vemos en la figura 2 tenemos que indicar al menos un tipo de fichero (Supported file type) aunque no tiene porqué ser el mismo tipo que vamos a usar, en este ejemplo he indicado ".xml" y casualmente voy a buscar ese tipo de fichero, pero como veremos en el código, también voy a indicar que me muestre los que tengan la extensión .txt (además de los .xml).

La forma de usar ese control es desde dentro de un método asíncrono (async) ya que las llamadas a los métodos para acceder al fichero son llamadas asíncronas.

En el siguiente código vemos lo que necesitamos para usar esa clase. Dependiendo del tipo de ficheros a los que queramos acceder así lo indicaremos en la colección FileTypeFilter, en este ejemplo he añadido dos tipos: .xml y .txt, pero si quisiéramos acceder a todos los tipos, habría que indicar el asterisco (*), en el ejemplo el asterisco está comentado, pero si quieres hacer pruebas, quita el comentario.

Este es el código de Visual Basic, el de C# está más abajo.

Dim openPicker As New FileOpenPicker()
openPicker.FileTypeFilter.Add(".xml")
openPicker.FileTypeFilter.Add(".txt")
'openPicker.FileTypeFilter.Add("*")
openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary
openPicker.ViewMode = PickerViewMode.List
Dim cfgFile As StorageFile = Await openPicker.PickSingleFileAsync()

If cfgFile Is Nothing Then Exit Sub

Dim sr = New StreamReader(Await cfgFile.OpenStreamForReadAsync)

 

Utilizando ese código podremos ver algo como la captura de la figura 3.

FileOpenPicker 01

Figura 3. El FileOpenPicker en acción

 

Y esto es prácticamente todo… aquí te dejo el código de ejemplo de C# para que no te quejes si prefieres los puntos y comas 😉

FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".xml");
openPicker.FileTypeFilter.Add("*");
openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
openPicker.ViewMode = PickerViewMode.List;
StorageFile cfgFile = await openPicker.PickSingleFileAsync();

if (cfgFile == null) return;

var sr = new StreamReader(await cfgFile.OpenStreamForReadAsync());

 

Comentarte que la clase FileOpenPicker está definida en Windows.Storage.Pickers y la clase StorageFile está definida en Windows.Storage.

Y esto ya si que es todo…

Nos vemos.

Guillermo

Dónde poner el ScrollViewer para poder hacer scroll (app para Windows Store)

 

Pues eso… que siempre me lío y no me aclaro nunca dónde tengo que poner el "dichoso" control ScrollViewer para poder hacer scroll al contenido… ahora que lo escribo tiene su lógica… es decir, si hago la pregunta: ¿dónde lo pongo para poder hacer scroll al contenido? La respuesta es: el ScrollViewer fuera, y dentro del control pondremos lo que haya que hacer scroll… si es que… :-/

Así que, ya sabes… defines el control ScrollViewer y dentro del control pones la caja de texto o lo que sea, y a eso es a lo que podrás hacer scroll (desplazamiento).

Por ejemplo, en el siguiente código XAML tenemos un ScrollViewer que está dentro de un Grid y que contiene una caja de texto (TextBlock) y al contenido de esa caja de textos es a lo que quiero poder hacer scroll. Ese TextBlock está a su vez dentro del un StackPanel, con idea de que ahí puedas meter más cosas y todas esas cosas estarán controladas por el control  de scroll. En este código de ejemplo también hay un botón que estará debajo de la caja de texto.

<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Visible">
    <StackPanel Margin="10" 
                HorizontalAlignment="Center" 
                VerticalAlignment="Center">
        <TextBlock x:Name="txtDatos" TextWrapping="Wrap" 
                   FontSize="16" FontWeight="SemiBold"
                   Text="El contenido del fichero"
                   MinWidth="800" MinHeight="600" />
        <Button Content="Leer un fichero" Margin="0,10,0,0"
                Click="Button_Click" />
    </StackPanel>
</ScrollViewer>

En esta captura puedes ver (por decir algo) cómo queda esto al funcionar en el emulador:

scrollviewer

Y ya está. Esto es todo amigos…

 

Nos vemos.

Guillermo

Mostrar un DialogBox o mensaje de diálogo en app de Windows Store

 

Pues eso… que lo debo tener (y lo tengo) por ahí, pero no sé si está bien "indexado", así que… aquí pongo el ejemplo y el texto para que sea fácil de encontrar (que no de buscar).

Además te cuento que el diálogo, al usar await, no se puede mostrar dentro de un bloque try/catch, así que… hay que buscar la solución… por ejemplo usando variables que indiquen si ha habido un error y cuál es el texto del error… y después fuera del bloque de error compruebas si tienes que mostrar o no el cuadro de diálogo… por ejemplo.

Para ir abriendo boca… esta sería la forma de mostrar un cuadro de diálogo en una aplicación de Windows Store:

Lo que tienes que hacer es crear un nuevo objeto del tipo MessageDialog que está definido en Windows.UI.Popups y asignarle el valor del mensaje a mostrar (este valor se lo puedes pasar directamente en el constructor) y el título del cuadro de diálogo.

En el siguiente ejemplo se muestra el cuadro de diálogo usando el texto que están en dos variables.

Fíjate que hay que usar await para llamar al método ShowAsync, por tanto la llamada se debe hacer desde un método que también sea asíncrono (hay que usar la cláusula async en la definición del método).

En Visual Basic:

Dim dlg = New Windows.UI.Popups.MessageDialog(sMsg)
dlg.Title = sTitle
Await dlg.ShowAsync()

 

En C#:

var dlg = new Windows.UI.Popups.MessageDialog(sMsg);
dlg.Title = sTitle;
await dlg.ShowAsync();            

El resultado sería el mostrado en la figura 1:

dialogo

Figura 1. Mostrando un mensaje al estilo de DialogBox

 

Bueno, pues esto es todo lo que quería contarte/contarme… ya que en realidad muchas de estas cosas las uso para mí mismo, que con la memoria que tengo… pues eso… 😉

 

Nos vemos.

Guillermo

Mira que soy torpe o el Guille y los tiles de Windows 8.1 Preview

 

Pues eso… que estaba haciendo pruebas (en mi aplicación del Reloj para Windows 8) para utilizar los nuevos tamaños de los iconos de la aplicación en la página de Inicio (también conocidos como tiles) y no me mostraba el tamaño grande.

He estado mirando en la documentación y en los ejemplos (de C# porque de VB no hay todavía para la preview de Windows 8.1) a ver si había algo especial que hacer, me encontré que ahora se indica la versión (version) del elemento visual al número 2:

<visual version="2">

También he visto que se puede indicar fallback con el tipo de template xml anterior, con idea de que si el indicado no está que se use ese otro (que suelen ser iguales):

<binding template="TileSquare150x150Block" fallback="TileSquareBlock">

Pero nada. No me mostraba los nuevos tamaños, solamente los dos que ya tenía: cuadrado y alargado (ahora mediano y ancho).

 

Y después de hacer algunas miles de millones de pruebas (exageradillo que es el niño) resulta que me da por mirar el "manifiesto" de la aplicación y… ¡torpeeeeeeee! ¡queresmutorpe! (me lo digo yo a mi mismo)

Pues resulta que no había imágenes para el tamaño grande, y por tanto… ¡no se puede mostrar ese tamaño en el tile!

Así que… si quieres que tu aplicación soporte todos los tamaños en los tiles, debes tener relleno todos los campos de los tamaños (ver la figura 1).

 

Screenshot (16.1)
Figura 1. Los tamaños del icono / tile soportados por la aplicación

 

Lo dicho, que tengo una memoria de pez olvidadizo y que además de eso más de la mitad de lo que pesa mi cerebro en vez de corteza cerebral es de torpeza cerebral… en fin… :-/

 

Espero que te sirva… y ya ni te pido que dones algo porque se ve que no estás por la labor… yo tampoco lo haría… ¡pa que te voy a decir otra cosa!

 

Nos vemos.
Guillermo

Cambios radicales en Windows 8.1 Preview (para developers)

 

 

Nota del 08/Jul/13 17:00:
Ayer noche publiqué este artículo, y esta mañana he estado haciendo ciertas comprobaciones, y entre ellas he modificado parte del código que te muestro, además de un pequeño truco para seguir usando los elementos VisualState que ya tengamos en el código XAML, aunque ya no existan como "modos de visualización".
La forma de usar o indicar cuál de los elementos VisualState definidos en el código XAML queremos usar (si hubiera alguno, si no existe ese "aspecto visual" simplemente lo ignora y no produce ningún efecto ni excepción) es haciendo una llamada al método GoToState de la clase VisualStateManager. Esa llamada la haremos en el código del método que intercepta el evento SizeChanged. En el código que te muestro más abajo utilizo esto que te estoy comentando.

 

Pues eso… que las cosas han cambiado con Windows 8.1 Preview con respecto a la versión anterior y las cosas que antes nos dijeron que eran de una forma, ahora resulta que no es así, y lo peor es que si no las cambias en tus aplicaciones de Windows 8 para Windows Store (Tienda de Windows) no quedarán "cool" y por tanto darán mucho el cante, es decir, que tus aplicaciones van a destacar, pero no por lo buenas o interesantes que puedan ser, si no porque parecerán aplicaciones que ni siquiera te has molestado en testear (probar).

Bueno, a lo mejor he sido un poco exagerado, ya que esto será así sobre todo si tu aplicación actual para la Tienda de Windows utiliza cosas como acoplarse a la izquierda o derecha (snapped) o tiene en cuenta si tiene otra aplicación acoplada o utiliza actualización del icono de la pantalla de Inicio (live tiles) y algunas cosas más…

Pero aquí estoy yo para intentar darte un poco de claridad en estas cosas que nos vienen encima, así que… empecemos con algunas cosas.

 

Las aplicaciones de Windows 8.1 pueden cambiar de tamaño

Pues eso es así, aunque con la filosofía de Windows 8, es decir, a pantalla completa.
Sí, sí, no me he equivocado, espera y te lo explico.
Las aplicaciones de Windows 8.1 (las que se utilizan para la pantalla de inicio, estilo metro o Modern UI) no funcionan en una ventana independiente, esas son las que funcionan en el escritorio, las propias de Windows 8 cuando las inicias, las veremos a pantalla completa. En la versión actual de Windows 8, además de pantalla completa hay otras dos formas de verlas: acoplada a uno de los dos lados (Snapped) o rellenando lo que deja una aplicación que esté en el modo acoplado (Filled).
Pero esto ha cambiado en Windows 8.1 y ahora los modos Snapped y Filled no existen. La pantalla se puede dividir para que podamos ver dos aplicaciones a la vez (como antes), pero en esta ocasión la división no tiene porqué ser tan evidente como antes, por ejemplo, en la figuras 1 y 2 tenemos cómo se verían las dos mismas aplicaciones usando Windows 8 (fig. 1) o Windows 8.1 Preview (fig. 2).

 

screenshot_07072013_173613_8
Figura 1. Windows 8: Aplicaciones en modo Snapped y Filled

 

screenshot_07072013_173815_8.1
Figura 2. Windows 8.1 Preview: Aunque parecido a Snapped y Filled, internamente no es así

 

Si miramos las dos capturas parece que no hay diferencia en las dos versiones de Windows 8 (salvo por la rayita que hay en la separación), pero si miras la siguiente figura (la 3), verás que la aplicación de la izquierda (que no está preparada para Windows 8.1) sigue manteniendo los tamaños de lo que antes era Snapped, pero ocupando más pantalla. Por otro lado, la aplicación para el tiempo si que se adapta al nuevo tamaño.

 

screenshot_07072013_173841_8.1
Figura 3. Windows 8.1 Preview: El tamaño ya no es fijo como en la versión anterior

 

Como detalle, decirte que en modo Snapped el ancho solía ser de 320 pixel y que en Windows 8.1 cuando inicialmente acoplamos la aplicación a uno de los dos lados, ese tamaño suele ser variable, por ejemplo, en una resolución de 1024 (que antes no permitía el modo Snapped) el ancho sería de 501 pixel, y en una resolución de 1366 ese ancho inicial es de 672 pixel.

 

Saber cuando la aplicación está en los "antiguos" modos Snapped o Filled

Para nosotros los developers (voy a usar la palabra en inglés, ya que algunas veces hay discrepancia entre el uso de desarrollador y programador) lo que debemos saber es que en Windows 8.1 ya no se podrán usar esos modos de visualización, bueno, no sólo no usarlos, lo peor es que no tenemos una forma fácil de saber si nuestra aplicación está en modo acoplado (Snapped) o no.

Lo que Microsoft recomienda o dice en la advertencia (ver figura 4) al usar la enumeración ApplicationViewState, o cuando queremos usar ApplicationView.Value (que es el que nos indica si la aplicación está en modo Snapped o Filled), es que tengamos en cuenta el tamaño al que se muestra nuestra aplicación y actuar en consecuencia.

 

Screenshot (14.1)
Figura 4. Advertencia (warning) al usar las propiedades y enumeraciones obsoletas

Resumiendo, el texto de la advertencia es: que la propiedad Value está obsoleta y que comprobemos directamente el tamaño de la ventana (Instead, query for window layout sizes directly).

Esto está muy bien, particularmente para las nuevas aplicaciones que hagamos, pero el problema es cuando esos tamaños los estamos utilizando en las aplicaciones existentes. La prueba la tienes en la figura 3, que a pesar de tener más espacio disponible, no se adapta al nuevo tamaño.

 

Nota:
Estoy usando la aplicación Microsoft Mahjong en estas capturas, pero podría estar usando muchas otras de las aplicaciones que hay para Windows 8, por ejemplo la de mi Reloj para Windows 8, en las que no se comprueban más cosas, simplemente porque en el momento de crear/publicar la aplicación no había más posibilidades de tamaño que pantalla completa, Snapped o Filled.

 

Como veremos dentro de un momento, me he fabricado unas funciones para saber si estamos o no en modo Snapped (o Filled, etc.) o lo que es lo mismo, cuando la aplicación está acoplada a uno de los dos lados y tiene un tamaño menor del que yo he predeterminado para simular esos valores.

Aunque tengas esas funciones, el problema real será si hemos usado (como ellos nos recomendaron) que la mayoría de los cambios en el tamaño de los controles, etc. lo hiciéramos dentro del código XAML (como elementos VisualState), ya que en Windows 8.1 Preview esos valores los ignoran completamente.

Por tanto, si queremos dar la misma funcionalidad a nuestra aplicación que la que ya teníamos, tendremos que convertir esos valores indicados en el diseño de la ventana en código directo y asignarlos en el evento SizeChanged del control o ventana.

Aunque también podemos indicar cuál de los VisualState que tenemos definido en el código XAML queremos usar. Esta opción es más adecuada, aunque podemos usar una mezcla de los dos, tal como veremos dentro de poco en el ejemplo final.

Y como también hay dos valores que se tenían en cuenta para manipular los tamaños de los objetos mostrados, como son si la aplicación está en modo horizontal (landscape) o en modo vertical (portrait), pues yo también me he fabricado un par de funciones para esas dos ocasiones.

Así que, veamos el código de las funciones que he definido y así será más fácil de entender el código que ponga para realizar esos cambios en el evento de cambio de tamaño de la ventana.

 

Funciones para simular Snapped y Filled o cómo saber si nuestra app está acoplada a uno de los lados

La definición del código la he hecho en la clase App, pero puedes hacerlo donde quieras, ya que están definidos como métodos compartidos (Shared en Visual Basic, static en C#).

En total he definido 6 métodos, dos de ellos para saber si está en modo Snapped o Filled. En estos dos utilizo una constante con el valor 750 para indicar que si el tamaño de la ventana (de la aplicación actual) es menor de esos 750 px y además la aplicación está anclada a la derecha o a la izquierda es que está en modo Snapped, por otro lado, considero que está en modo de relleno (Filled) si está ajustada a uno de los lados y el tamaño es igual o superior a esos 750 pixel. Por supuesto , en esta segunda consideración entrarían los modos en que estaría una aplicación cuando el usuario la está redimensionando (y el tamaño que le asigna es 750 o más), pero para ir viendo los cambios, ya nos vale, o, al menos, a mí me vale.

Nota:
El código que te mostraré es para Visual Basic, pero a diferencia de lo que han hecho la gente de Microsoft, también te mostraré el código de C#, pero no en el momento en que estoy escribiendo esto, pero lo pondré.

 

El código de Visual Basic de los métodos IsSnapped y IsFilled sería el siguiente:

 

Public Const AnchoSnapped As Double = 750

''' <summary>
''' Simular el modo Filled en Windows 8.1
''' Comprueba si la aplicación está en uno de los costados
''' y el ancho es mayor o igual que <see cref="AnchoSnapped"/> px
''' </summary>
''' <remarks>07/Jul/13</remarks>
Public Shared Function IsFilled() As Boolean
    Dim aView = ApplicationView.GetForCurrentView()
    Dim aWidth = Window.Current.Bounds.Width

    ' Si está acomplado a ambos lados es que es pantalla completa
    ' (esto es así cuando se cambia el tamaño estando acoplado)
    If (aView.AdjacentToLeftDisplayEdge AndAlso aView.AdjacentToRightDisplayEdge) Then
        Return False

    ElseIf (aView.AdjacentToLeftDisplayEdge OrElse aView.AdjacentToRightDisplayEdge) AndAlso
        aWidth >= AnchoSnapped Then

        Return True
    Else
        Return False
    End If
End Function

''' <summary>
''' Simular el modo Snapped en Windows 8.1
''' Si el ancho es menor de <see cref="AnchoSnapped"/> pixels
''' y está en uno de los lados lo considero Snapped
''' </summary>
''' <remarks>06/Jul/13</remarks>
Public Shared Function IsSnapped() As Boolean
    Dim aView = ApplicationView.GetForCurrentView()
    Dim aWidth = Window.Current.Bounds.Width

    ' Amplio las posibilidades comprobando solo si el tamaño es menor de AnchoSnapped
    ' ya que esté o no acoplada, el tamaño y posición del contenido debe adaptarse
    '
    'If (aView.AdjacentToLeftDisplayEdge OrElse aView.AdjacentToRightDisplayEdge) AndAlso
    '    aWidth < AnchoSnapped Then
    If aWidth < AnchoSnapped Then
        Return True
    Else
        Return False
    End If

End Function

 

Un par de cosas que quiero comentarte sobre el código anterior.

La primera es que estoy usando Window.Current.Bounds.Width para saber el ancho de la pantalla, y seguramente dirás que podría usar la propiedad ActualWidth de la ventana principal (no se puede desde este código porque la clase App no se deriva de Page), entre otras cosas porque es la forma que seguramente has podido ver en los ejemplos (para C#) que se incluyen con el SDK de Windows 8.1 Preview. Pero, he de decirte que esa propiedad a mí NUNCA me ha servido, siempre que lo he intentado el valor devuelto es 0.0, así que… he optado por esa otra que sé que funciona.

La segunda es el uso del nuevo método GetForCurrentView de la clase ApplicationView. Ese método devuelve un objeto del tipo ApplicationView que entre otras cosas contiene los dos valores que estoy usando en esas dos funciones: AdjacentToLeftDisplayEdge que nos indica si nuestra aplicación está acoplada a la izquierda de la pantalla, y AdjacentToRightDisplayEdge que como podrás suponer es para saber si la aplicación está acoplada a la derecha.

Tiempos aquéllos en las las funciones tenían unos pocos caracteres… mejor así, sobre todo si sabes algunas palabras de inglés.

Creo que el código no necesita mayor explicación, salvo indicar los cambios realizados en esta versión del lunes 8 de julio:

En el código de la función IsSnapped la he reducido a una simple comprobación de si el ancho de la pantalla es menor del que queremos considerar como "acoplado", en este ejemplo estoy usando el valor de la constante AnchoSnapped que inicialmente la he definido a 750 pixel.

En la función IsFilled ahora compruebo que no esté acoplado a ambos lados, ya que eso supondría que la aplicación está a pantalla completa, por tanto si se cumple la primera comprobación devuelve un valor falso, y por tanto solamente será verdadero cuando esté acoplado a uno de los dos lados y el ancho sea igual o mayor del indicado en AnchoSnapped.

 

Saber si la aplicación está en modo apaisado o vertical

Otras dos funciones que me he fabricado, más que nada para evitar estar repitiendo las definiciones de las llamadas al API de Windows 8.1 Preview (por medio de las clases de .NET Framework), son las que me indican si la aplicación está a pantalla completa y cómo está orientada la tableta o el dispositivo en el que está funcionando.

En la versión actual de Windows 8 esto lo hacíamos mediante los correspondientes valores de la enumeración ApplicationViewState, pero como ya hemos comprobado, se considera obsoleta.

Por ejemplo, para saber si nuestra aplicación estaba en modo de pantalla completa y en horizontal, comprobábamos si el valor de la propiedad Value de ApplicationView era FullScreenLandscape.

Ahora esto se hace comprobando si el valor de IsFullScreen es cierto y además el valor de Orientation es Landscape. Las dos primeras son nuevas propiedades de la clase ApplicationView y el valor de la propiedad Orientation es del tipo enumerado ApplicationViewOrientation.

Una vez dicho esto, podemos comprobar que las dos funciones que me he fabricado lo único que hacen es reducir un poco el código cuando queramos hacer las comprobaciones pertinentes.

Este es el código de Visual Basic de esas dos funciones.

 

''' <summary>
''' Comprobar si la pantalla está en FullScreenPortrait
''' (vertical a pantalla completa)
''' </summary>
''' <remarks>06/Jul/13</remarks>
Public Shared Function IsFullScreenPortrait() As Boolean
    Dim aView = ApplicationView.GetForCurrentView()

    If aView.IsFullScreen AndAlso aView.Orientation = ApplicationViewOrientation.Portrait Then
        Return True
    Else
        Return False
    End If
End Function

''' <summary>
''' Comprobar si la pantalla está en FullScreenLandscape
''' (apaisada a pantalla completa)
''' </summary>
''' <remarks>06/Jul/13</remarks>
Public Shared Function IsFullScreenLandscape() As Boolean
    Dim aView = ApplicationView.GetForCurrentView()

    If aView.IsFullScreen AndAlso aView.Orientation = ApplicationViewOrientation.Landscape The
        Return True
    Else
        Return False
    End If
End Function

 

Te comentaba que en total eran 6 funcionen las que me había fabricado, las otras dos simplemente devuelven un objeto del tipo ApplicationView (el valor devuelto por GetForCurrentView); y la otra función indica el ancho de la pantalla. Pero en el ejemplo que pondré ahora no se utilizan, por tanto, mejor las dejo ahí para otra ocasión.

 

Ejemplo para usar las funciones definidas

Veamos cómo usar estas funciones para adaptar el tamaño, margen, etc. de los controles según nuestra aplicación esté "acoplada" o no.

Este ejemplo es muy simple y sólo tiene dos controles TextBlock con distinto texto, uno servirá para el título y el otro para el texto a mostrar.

El aspecto en modo diseño es el que podemos ver en la figura 5.

 

Screenshot (15)

Figura 5. La página principal en modo diseño

 

Primero definimos los valores de los elementos VisualState, que en el ejemplo que estoy usando serían los indicados en el siguiente código XAML:

 

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

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="251*"/>
            <ColumnDefinition Width="640*"/>
            <ColumnDefinition Width="475*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="107*"/>
            <RowDefinition Height="384*"/>
            <RowDefinition Height="277*"/>
        </Grid.RowDefinitions>
        <TextBlock x:Name="txtTitle" Grid.Column="1" Text="El título" FontSize="110" />
        
        <TextBlock x:Name="txtMensaje" Grid.Column="0" Grid.Row="1" 
                   Grid.ColumnSpan="3" Grid.RowSpan="2"
                   VerticalAlignment="Center"
                   FontSize="140" FontWeight="Bold" TextWrapping="WrapWholeWords"
                   Text="El texto que ocupa la pantalla completa con cambio de línea" />

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="ApplicationViewStates">
                <VisualState x:Name="FullScreenLandscape" />
                <VisualState x:Name="FullScreenPortrait">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtTitle" Storyboard.TargetProperty="FontSize">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="90"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtMensaje" Storyboard.TargetProperty="FontSize">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="70"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Filled">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtTitle" Storyboard.TargetProperty="FontSize">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="80"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtMensaje" Storyboard.TargetProperty="FontSize">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="100"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Snapped">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtTitle" Storyboard.TargetProperty="FontSize">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="80"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="txtMensaje" Storyboard.TargetProperty="FontSize">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="70"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>

        </VisualStateManager.VisualStateGroups>

    </Grid>
</Page>


 

Todo esto lo haremos en el método del evento SizeChanged del control o página/ventana en el que queramos tener estas cosas en cuenta.

 

Private Sub MainPage_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged
    ' valor predeterminado de visualState                       (08/Jul/13)
    Dim visualState As String = "FullScreenLandscape"

    If App.IsFilled Then
        visualState = "Filled"
    ElseIf App.IsSnapped Then
        visualState = "Snapped"
    ElseIf App.IsFullScreenPortrait Then
        visualState = "FullScreenPortrait"
    Else
        visualState = "FullScreenLandscape"

        ' Si queremos adaptar los tamaños según el ancho
        ' lo podemos hacer aquí\f0
        ' Pero debemos tener en cuenta que el valor asignado en el código XAML
        ' tiene preferencia.
        ' En este ejemplo, esto sólo funciona cuando es FullScreenLandscape
        ' ya que no se asignan valores en el código XAML

        Dim ww = Window.Current.Bounds.Width
        If ww <= 800 Then
            txtTitle.FontSize = 70
            txtMensaje.FontSize = 70
        ElseIf ww <= 1024 Then
            txtTitle.FontSize = 80
            txtMensaje.FontSize = 90
        ElseIf ww < 1366 Then
            txtTitle.FontSize = 100
            txtMensaje.FontSize = 110

        Else
            ' Los valores predeterminados
            txtTitle.FontSize = 110
            txtMensaje.FontSize = 140
        End If

    End If

    ' Utilizar los valores del código XAML indicado al visualState indicado
    VisualStateManager.GoToState(Me, visualState, False)

    ' Si quisiéramos usar valores distintos a los inidcados en el código XAML
    ' tendremos que asignarlos aquí, después de llamar a VisualStateManager.GoToState

End Sub

 

Por favor lee los comentarios del código para que sepas cuando esas asignaciones al tamaño de la fuente del texto funcionan, ya que siempre tendrá preferencia el valor asignado en el código XAML y si queremos que el asignado manualmente sea el que "mande" debemos usar el truco que ahí indico.

 

Bueno, creo que con esto ya está bien para esta primera aproximación sobre los cambios que se incluyen en Windows 8.1 Preview y que los que queremos crear aplicaciones para la Tienda de Windows debemos tener en cuenta.

Hay más cosas, algunas te las contaré y de otras seguramente no te diré ni (las que no haya probado).

 

Espero que te se de utilidad y ya sabes, si quieres invitarme a un café virtual, puedes hacerlo en el botón "Donar" 😉

Gracias (incluso si no me invitas).

 

Nos vemos.

Guillermo

P.S.

Cuando tenga listo el código de C# pondré el proyecto de ejemplo en mi sitio de descargas (downloads) para que puedas verlo con más detalle.

un +1 a quién corresponda (plantillas de VB 12 para la Store)

 

Pues eso… revisando las plantillas que se incluyen en Visual Studio 2013 Preview -versión Professional- que estoy usando en una máquina virtual con Windows 8.1 Preview, he comprobado que está corregido el "fallo" que había en las plantillas de Visual Basic de los proyectos de tipo Grid y Split para la Tienda de Windows y que te comenté por aquí el 28 de Diciembre de 2012 (y no era una inocentada): Las plantillas de Windows Store o la dejadez para con Visual Basic.

En esa ocasión te dije que se hacía una asignación en el método OnLaunched de la clase App que no tenía en cuenta la conversión estricta de código (Option Strict On), y en esta ocasión sí está el código correcto, además usando TryCatch que es lo recomendable en esa asignación (por la comprobación posterior que se hace de si la variable que recibe el objeto tiene un contenido nulo o no).

Screenshot (10.1)

 

También te dije un par de cosas más, pero eso lo han solucionado con otra forma de usar los datos de ejemplo, que en esta ocasión tanto el código de VB como el de C# son similares.

 

Lo dicho… aunque ya les metí caña (en este post de elGuille.info en Facebook) por la falta de ejemplos para Visual Basic en el SDK de Windows 8.1 Preview: Windows 8.1 app samples, en esta ocasión tengo que decirles: ¡gracias por corregir el error!

 

Nos vemos.
Guillermo
P.S.
No sé si es por error o para que parezca que el código de Visual Basic no está convertido desde el de C#, en esta ocasión hay una diferencia de nombre en el método usado para saber si la ventana (de la clase SplitPage) ha cambiado de tamaño (SizeChanged), ya que en Visual Basic se llama Winow_SizeChanged y en C# es: Window_SizeChanged.
Fíjate que en VB es "WINOW" que le falta la letra "D", una tontería, pero… ¡jum! 😉

Si tu app de Windows Store debe recordar… ¡que recuerde!

 

Pues eso… ya que, como seguramente sabrás, cuando "te vas" de una aplicación diseñada para la Tienda de Windows (Windows Store / Metro / Modern UI) el propio sistema operativo puede ponerla en modo suspensión y cuando vuelve a tener el "foco", es decir, estar nuevamente activa y, por tanto, en primer plano, debería mostrarte lo que te estaba mostrando antes de perder el foco, es decir, que el usuario no "note" lo que el sistema operativo hace con nuestra aplicación, ya que si ve que prácticamente vuelve a empezar, nos echará la culpa a nosotros (los que hemos diseñado la aplicación), ya que el usuario "no entiende" de cosas técnicas, ni de suspensiones, ni casi de cómo usar la aplicación… ya puestos a criticar al usuario… jeje.

Aquí no te voy a explicar cómo hacer esto que te comento en nuestras aplicaciones para la Windows Store (pero quiero escribir sobre el tema, y puede que esta especie de "llamada al orden" acelere esa escritura, ya que desde hace algunos meses que quiero escribir sobre esto…).

 

win8 app

 

En realidad esto lo estoy escribiendo porque hace ya tiempo me pasó con el Internet Explorer para la Tienda de Windows (no el de escritorio), que estaba copiando algo (tenía un texto seleccionado) y "me salí" de la aplicación para ir al escritorio a pegar eso que había copiado en otra aplicación o no sé para qué me fui del IE, la cuestión es que cuando volví se volvió a "reiniciar" el Internet Explorer, aunque se quedó mostrando la página que yo había abierto, pero como si la hubiese recargado, y vale que no estuviese aún seleccionado el texto, pero al menos esperaba que la página estuviese en el mismo sitio en que la dejé… el texto que mostraba era nuevamente el del principio de la página.

Y hoy "jugando" con el Minesweeper (la versión del busca minas para la Tienda de Windows) me ha pasado algo parecido… estaba en uno de los retos diarios, me salí un momento para ver "algo" y cuando volví empezó a cargarse de nuevo (y conectándose con el usuario de la XBox -que no tengo, XBox me refiero-, pero que es lo que te permite hacer más cosas que los simples juegos o modos del juego…

Resumiendo que si los "creadores" de todo el tinglao este de las aplicaciones para la Tienda de Windows (léase Microsoft) no tienen en cuenta esas cosas que nos "recomiendan" al resto de los programadores (o desarrolladores o como quieras llamar a los pica-código) como vamos nosotros a confiar que funcione eso que ellos dicen que funciona y que debemos hacer para que nuestros usuarios tengan un (digamos) buen sentimiento hacia nuestras aplicaciones para la Tienda de Windows.

En fin…

 

Nos vemos.
Guillermo

P.S.
Esperemos que en la nueva revisión (Windows 8.1) algunas de estas "pegas" de las aplicaciones propias de Microsoft / Windows 8 ya estén solucionadas, ya que si tú quieres hacer que tus aplicaciones no "padezcan" de esos mismos problemas tendrás que tener en cuenta cómo estaba el estado de la aplicación antes de que el Sistema Operativo la suspendiera para poder restaurarla a ese mismo estado cuando "vuelva" nuevamente a la vida (esté activa).

cuando 4 horas de la Windows Store son más de 24

 

Pues eso… que en estos últimos días la gente de certificación de la Windows Store (Tienda de Windows) parece que no van mu finos…

En cuestión de dos días (o tres, si tenemos en cuenta que ya es viernes 17) la publicación de una de mis aplicaciones para la tienda de Windows (Reloj Windows 8 [la versión de pago/donativo]) lo está teniendo complicado.

Primero fue que a pesar de avisarme de que ya estaba disponible en la tienda, y después de esperar algunas (muchas) horas, seguía siendo la misma versión la que se mostraba tanto usando el explorador como en la propia aplicación de la Tienda de Windows (la información mostrada seguía indicando que era la versión 1.5, pero en realidad debería ser la 1.7).

Así que… decidí mandarla de nuevo, usando el mismo paquete de instalación (AppPackage / appxupload), anoche (16 de mayo) a la 01.32 recibo un mensaje indicándome que ya había aprobado la certificación y que estaría en la Tienda "tan pronto como se publique, después del 15 de mayo a las 13:11" (el día anterior) (ver la figura 1)

tienda 1
Figura 1. Ya queda menos…

 

Pero resulta que hace un rato miré cómo estaba el tema y mi sorpresa fue que aún estaba en la fase final: Firmado y publicación (Signing and publishing) que como puedes comprobar en la figura 2 suele tardar sólo 4 horas.

tienda 2
Figura 2. Las 4 horas…

 

Aunque… ahora que lo pienso… lo mismo es porque el horario que usarán será el del Pacífico (unas 8 o 9 horas menos que en España).

 

Nota:
Que no me quejo ni estoy molesto, sólo lo comento como curiosidad/anécdota o por si te pasa algo parecido para que… simplemente esperes… que puede que cada día haya más gente haciendo aplicaciones para Windows 8 (o Windows Server 2012) y claro, se tarde más en hacer todos los trámites.

 

Nos vemos.
Guillermo

P.S. (17/may/13 15.37)
Aunque me sigue indicando que aún no está publicada, sí que está disponible en la Tienda de Windows la última versión enviada (v1.7).
Este es el enlace corto a la descripción en castellano de Reloj Windows 8.
El enlace te llevará a la aplicación en la Tienda de Windows (al menos si lo utilizas desde Internet Explorer).

P.S. 2 (17/may/13 16.38)
Pues resulta que la que ahora está en la Tienda de Windows es la que mandé inicialmente, es decir, es la misma que mandé anteayer y que no aparecía actualizada.
Por tanto, el ejecutable es el mismo (mandé el mismo paquete de la aplicación) pero la descripción de los cambios no está completa… en la próxima ya estará bien… ¡aunque tarde más de lo esperado! 🙂

si notas que tu Windows 8 va lento…

 

Pues… seguramente es porque no tienes activadas las actualizaciones automáticas.

O eso o que casualmente me ocurre siempre que cambio la puñetera configuración de las actualizaciones automáticas…

Primero (al principio de tener el Windows 8 Pro) las puse para que descargara las actualizaciones y yo decidiera cuándo instalarlas. Pues bien… algunas veces notaba muy pesado el Windows… ¿sabes? eso de que abres o restauras el Visual Studio (u otra aplicación de escritorio) y parece que cada pixel lo están pintando de forma artesanal…

Decidí cambiar la configuración para que siempre instale las actualizaciones y "aparentemente" todo iba bien…

El problema que yo le veo a las actualizaciones de Windows 8, al menos si entras usando la configuración del PC desde la pantalla de Inicio (Modern UI que llaman ahora) es que si las automatizas tienes como menos control sobre ellas… aunque (por suerte para algunos) siempre nos queda la opción de entrar desde el escritorio y hacer los cambios que creas conveniente (yo es que estoy/estaba acostumbrado con el Windows 7 a "obligar" algunas veces a que buscase actualizaciones, sobre todo en esas noches que sabía que iba a estar "concentrado" a la hora de las actualizaciones automáticas: las 3 de la madrugada).

Pues bien… ayer (o anteayer) cambié nuevamente la forma de actualizar mi equipo, pero esta vez lo puse manual, es decir, que ni descargara ni nada, sólo que comprobase cuándo había nuevas actualizaciones (ver la figura 1).

 

w8 actualiciones 1
Figura 1. Las opciones de actualización de Windows 8

 

Y hoy estaba muy lento (creo que desde anoche), así que… me he dicho: voy a mirar cómo va esto de las actualizaciones, que casi seguro que hay alguna nueva… y sí, había nuevas actualizaciones: ¡21 ni más , ni menos! tal como puedes comprobar en la figura 2.

 

w8 actualiciones 2
Figura 2. Muchas actualizaciones para un día y medio…

 

Así que… creo que lo voy a dejar en "automático" y de vez en cuando entraré en la ventana de Windows Update por si hay que instalar alguna cosa que no instale automáticamente o quiera "forzar" la instalación si ese día (o noche) me quedaré haciendo cosas a la hora de la actualización automática.

 

Conclusión:
Se puede criticar esta falta de fluidez por culpa (presuntamente) de las actualizaciones automáticas., pero también se pueden buscar alternativas… o hacer ambas cosas: buscar la alternativa, que resulta que desde mi punto de vista es que esté en modo automático y criticar (más bien para desfogarse uno) o comentar el hecho para que otra gente sepa porqué puede notar su Windows 8 lento y/o pesado… 😉

 

Nos vemos.
Guillermo