Archivo por meses: enero 2013

y yo pensaba que convertir fechas y horas ya no sería más un calentamiento de cabeza

 

Pues eso… que sigue siendo… al menos si utilizas "tu formato preferido", aunque sea con otro "locale"… en fin… que no recuerdo yo desde cuando no tenía problemas para convertir una cadena con el formato de una fecha (supuestamente de forma correcta) a un objeto de tipo DateTime. A la memoria me vienen los tiempos del VB6 (o cualquier otro anterior a VB.NET) y sobre todo me acuerdo de cuando estaba escribiendo el código de mis foros con Visual Studio 2005 (ASP.NET 2.0).

Y hoy va y me da este regalito el Visual Studio 2012:

 

error al convertir fechas
Figura 1. Error al convertir 31/01/2013 20:40:00 a una fecha…

Así que… he tenido que optar por "salir del paso" convirtiendo "a mano" esas fechas erróneas y a usar el formato "yankee" para no tener problemas posteriores… espero que así sea…

 

Te explico que todo ese "follón" es porque quiero guardar el contenido de una clase definida por mí mismo en los "settings" de Windows 8, con idea de poder usarla la próxima vez que ejecute la aplicación.

En mi clase he sobrescrito el método ToString para que devuelva una cadena que posteriormente la pueda pasar desde lo que es, un tipo string, al tipo que he definido. Y ese ToString tiene el equivalente FromString para que devuelva un objeto usando el contenido de una cadena (con el formato que previamente he definido… o casi).

El "problema" era que yo dejaba que el propio .NET se encargara de convertir la fecha en cadena, es decir, no usaba ningún formato específico, por tanto el formato devuelto es: #d/M/yyyy h:m:sAM/PM# (o más o menos) y claro, la cadena usada era diferente… total un follón.

Así que… además de la comprobación manual, ahora lo que he hecho es que el método ToString devuelve la fecha con este formato: Fecha.ToString("#M/d/yyyy HH:mm:00#") y que salga el sol por Antequera

El "00" para los segundo es porque en este caso quiero que los segundos siempre sean 00, ya que es para una alarma en la que ese espacio de tiempo no se tiene en cuenta…

 

Te muestro parte del código que ahora estoy usando y lo que he tenido que hacer para salir del paso… (sabiendo que el error es porque el formato es dd/MM/yyyy HH:mm:ss, por eso no hay más comprobaciones en el caso de que falle la conversión del DateTime.TryParse.

 

Private Const elSeparador As String = ","

''' <summary>
''' Devuelve una cadena con los datos básicos:
''' Fecha y Mensaje.
''' Si se devuelven más datos, 
''' devolver el mensaje siempre al final.
''' </summary>
Public Overrides Function ToString() As String
    Return String.Format("{0}{2} {1}", Fecha.ToString("#M/d/yyyy HH:mm:00#"), Mensaje, elSeparador)
End Function

''' <summary>
''' Devuelve un objeto Alarma a partir del contenido
''' de una cadena, en el formato: "Fecha, Mensaje"
''' (el devuelto por <see cref="ToString"/>)
''' En lugar de la coma se usará el caracter indicado en <see cref="elSeparador"/>
''' </summary>
Public Shared Function FromString(s As String) As Alarma
    Dim it As New Alarma

    Dim i = s.IndexOf(elSeparador)
    If i = -1 Then
        Return Nothing
    End If

    If DateTime.TryParse(s.Substring(0, i), it.Fecha) = False Then
        Dim s1 = s.Substring(0, i)
        ' si da el error es porque está en formato dd/MM/yyyy HH:mm:ss
        Dim dia = CInt(s1.Substring(0, 2))
        Dim mes = CInt(s1.Substring(3, 2))
        Dim año = CInt(s1.Substring(6, 4))
        Dim hora = CInt(s1.Substring(11, 2))
        Dim minuto = CInt(s1.Substring(14, 2))
        it.Fecha = New DateTime(año, mes, dia, hora, minuto, 0)
    End If
    'it.Fecha = CDate(s.Substring(0, i))
    it.Mensaje = s.Substring(i + 1).TrimStart()

    Return it
End Function

 

Sólo lo muestro en VB porque en C# no lo estoy usando para este programa, pero como comprobarás no es un código demasiado complicado… creo… 😉

 

Pues ya está… ahí queda eso… para que no te confíes con las fechas desde cadena… 😉

 

Nos vemos.

Guillermo

Usar el corrector ortográfico del control TextBox (Windows Store)

 

Pues eso… que el control TextBox que viene en el Visual Studio 2012 para las aplicaciones de la Tienda de Windows (Windows Store / Windows 8 / estilo Metro) tiene una propiedad llamada IsSpellCheckEnabled que si le asignamos un valor verdadero utilizará el corrector ortográfico y nos marcará las palabras que no reconozca, que no quiere decir que no estén bien…

La asignación la podemos hacer en modo de diseño (y supongo que por medio de código en el constructor de la clase / página en la que esté definido esa caja de textos que queremos que use el corrector ortográfico).

Este es el código que he usado en la aplicación en el que lo voy a utilizar (es la primera vez que uso un control con corrección ortográfica, al menos de forma consciente).

 

<TextBox x:Name="txtTexto" Grid.Column="1" Grid.Row="1" Text="" 
     Width="Auto" MinWidth="200" Margin="0,6" IsSpellCheckEnabled="True" 
         TextWrapping="Wrap" Height="80"/>

 

Y en esta captura lo puedes ver en acción:

 

IsSpellCheckEnabled

Figura 1.

 

Algunas palabras las corrige automáticamente y otras, simplemente te las marca como no válidas.

Y por supuesto te da la opción de corregirla (figura 2)… siempre que el corrector "sepa" cómo hacerlo.

 

IsSpellCheckEnabled 02

Figura 2. Opciones del corrector ortográfico

 

 

Nos vemos.

Guillermo

Publicada mi segunda app en la Windows Store

 

Pues eso… después de casi 5 días de espera, en realidad 4 + 1, ya que en los primeros días me la rechazaron dos veces (en otro momento te comentaré las razones y cómo evitarlas antes de que ocurran) y hoy la volví a mandar y ya está publicada en la Tienda de Windows (Windows Store).

 

lector Rss free en Windows Store
Si pulsas en la imagen te llevará a la página de información y desde allí podrás entrar en la tienda de Windows, siempre que uses Internet Explorer, ya que con Chrome no va a ningún lado el enlace de "Ver en la Tienda de Windows".

 

Esta es la versión gratuita, la versión de pago (que es igual que la free, pero con dos idiomas, es para que la gente que se la baje/compre pueda colaborar económicamente con mi sitio) seguramente estará disponible en unos minutos, ya que me han mandado el mensaje indicándome que está "aprobada".

 

En esta página de mi sitio te pondré los enlaces a las actualizaciones que vaya haciendo y (cuando lo tenga listo) al código fuente para que te pueda servir de ayuda… ¡espero!

 

Y esto es todo…

 

Nos vemos.,
Guillermo

Subida a la Cuesta del Cielo, domingo 20 enero 2013

 

Pues eso… que hoy domingo 20 de enero de 2013 hemos ido de "excursión" a la cuesta del cielo (o pico del cielo) en la sierra de Nerja, ha hecho mucho viento y sobre todo cuando estábamos arriba del todo, hacía un frío que… ¡ofú qué frío! yo los deos los tenía que no los sentía, como si me hubiese dado un porrazo contra la pared y de frente, así era la sensación que tenía en los dedos… pero después ya… entraron en calor, en la bajada… que es donde más he notado la caminata… vaya dolorcillo que noto sobre todo en las plantas de los pies… pero bueno,  no es plan de quejarse… también hay fotos… lo que pasa que aún las tengo que "revelar", así que… mientras tanto, te dejo un par de ellas para que "nos veáis"; y ya pondré el resto o mejor dicho, ya pondré el enlace a las fotos… que han sido casi 120 y… pues eso…

Estas dos fotos son de la antes de salir, y la otra cuando ya estábamos arriba del todo… adivina cuál es cuál… 😉

 

P1180844_lr
Foto 1. Antes de empezar la caminata (08.43)

La cruz está detrás...
Foto 2. En la cima de la cuesta del cielo (12.50)
(aquello plateado que se ve detrás es la cruz)

 

 

Para el recuerdo:

 

Esta es del 29 de octubre de 1972, pero no es la cuesta del cielo, aunque nuestra intención fue llegar allí… pero nos perdimos… la siguiente vez que fuimos fue poco después de un incendio que hubo y de que llevaran la cruz, y gracias a las marcas que dejaron pudimos llegar…

 

19721029 N005-26

 

Estas dos son del 16 de marzo de 1975, que como se puede apreciar había nevado.
no es que me acuerde de la fecha, es que la puse en las fotos después de escanearlas 😉

 

19750316 N062-29

 

19750316 N062-27
— con Mari Carmen Campillos Gallardo y Lita
Que tuvimos que ir a por nieve y llevársela para que terminaran de subir… 😉

 

Nos vemos.
Guillermo

Crear un SplashScreen personalizado para la Windows Store

 

Pues eso… que en las aplicaciones para la Tienda de Windows te "exigen" que tengas una imagen de al menos 620×300 para usar como pantalla de presentación (splash screen) mientras la aplicación se carga.

Si quieres poner algún texto en esa imagen, dicho texto debe ser estático, es decir, cada vez que lo cambies en realidad estarías cambiando la imagen, y lo que te voy a explicar aquí es cómo añadir textos (o cualquier otra cosa) a esa imagen de inicio, pero de forma que sólo se añada (o sea visible) mientras está cargando el programa.

 

Nota:
Este ejemplo está basado, y creo que mejorado, pero sobre todo simplificado, en los ejemplos de la MSDN / SDK:

Cómo extender la pantalla de presentación y Directrices y lista de comprobación para pantallas de presentación, en concreto el ejemplo de C# para Evitar un parpadeo durante la transición a la pantalla de presentación extendida.

 

En este ejemplo he procurado que, en modo de diseño, la imagen esté centrada y dentro de un Grid con idea de que podamos situar los textos donde queramos que estén.

Hay que tener en cuenta que aquí estoy usando la imagen predeterminada de 620×300 pero si utilizas alguna de las otras dos, debes tenerlo en cuenta a la hora de posicionar los textos.

He dejado la imagen predeterminada, es decir, la que utiliza el Visual Studio al crear un nuevo proyecto, por tanto, los valores de las columnas y filas del Grid puede que no sean los adecuados si tienes otra imagen.

Lo que si es conveniente saber es que el ancho y alto de esas columnas y filas deben coincidir con el tamaño de la imagen, ya que así tendremos una visión exacta de dónde estarán posicionados las cosas que le añadamos a esa imagen de inicio.
En este ejemplo he usado el logo pequeño de la aplicación (SmallLogo.png) y un par de cajas de textos, una de ellas la modifico (si es necesario) en tiempo de ejecución.

En la siguiente captura puedes ver cómo quedaría con el código de ejemplo usado en este artículo.

 

ExtendedSplash

 

 

Nota:
El color de fondo de la pantalla de inicio y de la aplicación deberían coincidir con el indicado en el manifiesto de la aplicación (Package.appxmanifest), ya que si no… pues… lo mismo no queda bien.
Fíjate que en el manifiesto de la aplicación hay dos definiciones de colores, uno para las imágenes "normales" (los logos) y otro para la pantalla de inicio (Splash screen). Yo los he puesto todos (también el de MainPage) con el mismo color verde: #185F18.

 

Vamos a ver el código XAML de la página/control que hará de pantalla de inicio en este ejemplo.

 

Código Xaml El código Xaml
<Grid
    x:Class="Splash_Screen.ExtendedSplash"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="using:Splash_Screen"
    mc:Ignorable="d"
    Background="#185F18">

    <!-- la imagen tiene 620 x 300 -->
    <Canvas MaxHeight="300" MaxWidth="620">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="35" />
                <RowDefinition Height="225" />
                <RowDefinition Height="40" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="60"/>
                <ColumnDefinition Width="140"/>
                <ColumnDefinition Width="420"/>
            </Grid.ColumnDefinitions>

            <Image x:Name="extendedSplashImage" Grid.Row="0" Grid.Column="0"
                   Grid.RowSpan="4" Grid.ColumnSpan="4" 
                   Margin="0" Source="///Assets/SplashScreen.png" 
                   ImageOpened="extendedSplashImage_ImageOpened"/>
            <TextBlock x:Name="txtTitulo" x:Uid="txtTitle" 
                       Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
                       Foreground="White" FontSize="18" FontWeight="Bold" 
                       HorizontalAlignment="Center"
                       Text="Prueba de Splash Screen personalizada" />
            <TextBlock x:Name="txtCopyr" Grid.Row="2" Grid.Column="2" 
                       Foreground="White" FontSize="15" FontWeight="Bold" 
                       Margin="0,10,0,0"
                       Text="©Guillermo Som (elGuille), 2013" />
            <Image Grid.Row="2" Grid.Column="0" Grid.RowSpan="2"
                   Height="30" Width="30" Stretch="Uniform" 
                   Source="///Assets/SmallLogo.png" Margin="0,0,0,10"  Opacity="100" />
        </Grid>
    </Canvas>
</Grid> 

 

Nota sobre las tres /// que hay delante de la carpeta en la que están las imágenes:

Esas tres barras indican que es desde el directorio base de la aplicación, de esa forma, si mueves este fichero de la Splash screen a otra carpeta no tendrás que hacer cambios para indicar la ruta de las imágenes.

 

Ahora veamos el código de esa página, como verás hay dos constructores, pero nosotros solo usaremos el que recibe dos parámetros.

 

Código para Visual Basic.NET (VB.NET) El código para Visual Basic .NET
'------------------------------------------------------------------------------
' ExtendedSplash                                                    (19/Ene/13)
' Usar un SplashScreen personalizado
'
' Basado en un ejemplo de la MSDN (y creo que mejorado y simplificado)
' Sólo hay que modificar App.OnLaunched
'
' Cómo extender la pantalla de presentación
' http://msdn.microsoft.com/es-es/library/windows/apps/xaml/hh868191.aspx
' y Directrices y lista de comprobación para pantallas de presentación para
' Evitar un parpadeo durante la transición a la pantalla de presentación extendida
' http://msdn.microsoft.com/es-es/library/windows/apps/hh465338.aspx#ts_flicker_cs
'
'
' ©Guillermo 'guille' Som, 2013
'------------------------------------------------------------------------------

Imports System
Imports Windows.ApplicationModel.Activation
Imports Windows.Foundation
Imports Windows.UI.Core
Imports Windows.UI.Xaml
Imports Windows.UI.Xaml.Controls

Partial Class ExtendedSplash
    ' Rect to store splash screen image coordinates. 
    Friend splashImageRect As Rect
    ' Variable to track splash screen dismissal status. 
    Friend dismissed As Boolean = False
    ' Variable to hold the splash screen object. 
    Private splash As SplashScreen

    Friend rootFrame As Frame


    Private showWindowTimer As DispatcherTimer
    Private showWindowTimerNum As Integer = 0

    Private Sub OnShowWindowTimer(sender As Object, e As Object)
        showWindowTimerNum += 1

        If showWindowTimerNum = 1 Then
            ' Activate/show the window, now that the splash image has rendered
            Window.Current.Activate()

            ' aquí hacemos un pequeño descanso antes de mostrar
            ' la página principal
        ElseIf showWindowTimerNum >= 50 Then
            showWindowTimer.Stop()
            cargarMainPage()
        End If

    End Sub

    Private Sub extendedSplashImage_ImageOpened(sender As Object, e As RoutedEventArgs)
        ' ImageOpened means the file has been read, but the image hasn't been painted yet.
        ' Start a short timer to give the image a chance to render, before showing the window
        ' and starting the animation.
        showWindowTimer = New DispatcherTimer()
        showWindowTimer.Interval = TimeSpan.FromMilliseconds(50)
        AddHandler showWindowTimer.Tick, AddressOf OnShowWindowTimer
        showWindowTimer.Start()

    End Sub

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.

    End Sub

    ''' <summary> 
    ''' Constructor with splash screen information 
    ''' </summary> 
    Public Sub New(splashscreen As SplashScreen, loadState As Boolean)
        InitializeComponent()

        If DateTime.Now.Year > 2013 Then
            txtCopyr.Text = "©Guillermo Som (elGuille), 2013-" & DateTime.Now.Year.ToString
        End If

        ' Listen for window resize events to reposition the extended splash screen image accordingly. 
        ' This is important to ensure that the extended splash screen is formatted properly in response to
        ' snapping, unsnapping, rotation, etc... 
        AddHandler Window.Current.SizeChanged, AddressOf ExtendedSplash_OnResize

        splash = splashscreen

        If splash IsNot Nothing Then
            ' Register an event handler to be executed when the splash screen has been dismissed. 
            AddHandler splash.Dismissed, AddressOf DismissedEventHandler

            ' Retrieve the window coordinates of the splash screen image. 
            splashImageRect = splash.ImageLocation
            PositionImage()
        End If

        ' Create a Frame to act as the navigation context  
        rootFrame = New Frame()

        '' Restore the saved session state if necessary 
        'RestoreStateAsync(loadState)


    End Sub

    'Public Async Sub RestoreStateAsync(loadState As Boolean)
    '    If loadState Then
    '        Await SuspensionManager.RestoreAsync()
    '    End If
    '    ' Normally you should start the time consuming task asynchronously here and  
    '    ' dismiss the extended splash screen in the completed handler of that task 
    '    ' This sample dismisses extended splash screen in the handler for "Learn More" button for demonstration 
    'End Sub

    ' Position the extended splash screen image in the same location as the system splash screen image. 
    Private Sub PositionImage()
        extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X)
        extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y)

        extendedSplashImage.Height = splashImageRect.Height
        extendedSplashImage.Width = splashImageRect.Width
    End Sub

    Private Sub ExtendedSplash_OnResize(sender As Object, e As WindowSizeChangedEventArgs)
        ' Safely update the extended splash screen image coordinates.
        ' This function will be fired in response to snapping, unsnapping, rotation, etc... 
        If splash IsNot Nothing Then
            ' Update the coordinates of the splash screen image. 
            splashImageRect = splash.ImageLocation
            PositionImage()
        End If
    End Sub

    Private Sub cargarMainPage()
        ' Navigate to MainPage 
        rootFrame.Navigate(GetType(MainPage))

        '' Set extended splash info on Main Page 
        'DirectCast(rootFrame.Content, MainPage).SetExtendedSplashInfo(splashImageRect, dismissed)

        ' Place the frame in the currrent window 
        Window.Current.Content = rootFrame

    End Sub

    ' Include code to be executed when the system has transitioned from the splash screen to the extended splash screen (application's first view). 
    Private Sub DismissedEventHandler(sender As SplashScreen, e As Object)
        dismissed = True

        ' Navigate away from the app's extended splash screen after completing setup operations here... 
        ' This sample navigates away from the extended splash screen when the "Learn More" button is clicked. 
    End Sub
End Class

 

 

Código para C Sharp (C#) El código para C#
//-----------------------------------------------------------------------------
// ExtendedSplash                                                   (19/Ene/13)
// Usar un SplashScreen personalizado
//
// Basado en un ejemplo de la MSDN (y creo que mejorado y simplificado)
// Sólo hay que modificar App.OnLaunched
//
// Cómo extender la pantalla de presentación
// http://msdn.microsoft.com/es-es/library/windows/apps/xaml/hh868191.aspx
// y Directrices y lista de comprobación para pantallas de presentación para
// Evitar un parpadeo durante la transición a la pantalla de presentación extendida
// http://msdn.microsoft.com/es-es/library/windows/apps/hh465338.aspx#ts_flicker_cs
//
//
// ©Guillermo 'guille' Som, 2013
//------------------------------------------------------------------------------

using System;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Splash_Screen
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class ExtendedSplash : Grid
    {
        public ExtendedSplash()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Constructor with splash screen information
        /// </summary>
        public ExtendedSplash(SplashScreen splashscreen, bool loadState)
        {
            InitializeComponent();

            //
            // Aquí pondremos lo que haya que actualizar en los textos
            //
            if (DateTime.Now.Year > 2013)
            {
                txtCopyr.Text = "©Guillermo Som (elGuille), 2013-" + DateTime.Now.Year.ToString();
            }

            // Listen for window resize events to reposition the extended splash screen image accordingly.
            // This is important to ensure that the extended splash screen is formatted properly in response to
            // snapping, unsnapping, rotation, etc...
            Window.Current.SizeChanged += ExtendedSplash_OnResize;

            splash = splashscreen;

            if (splash != null)
            {
                // Register an event handler to be executed when the splash screen has been dismissed.
                splash.Dismissed += DismissedEventHandler;

                // Retrieve the window coordinates of the splash screen image.
                splashImageRect = splash.ImageLocation;
                PositionImage();
            }

            // Create a Frame to act as the navigation context
            rootFrame = new Frame();

            // Restore the saved session state if necessary
            //RestoreStateAsync(loadState);


        }
        
        //async void RestoreStateAsync(bool loadState)
        //{
        //    if (loadState)
        //        await SuspensionManager.RestoreAsync();

        //    // Normally you should start the time consuming task asynchronously here and  
        //    // dismiss the extended splash screen in the completed handler of that task 
        //    // This sample dismisses extended splash screen  in the handler for "Learn More" button for demonstration 
        //} 


        // Rect to store splash screen image coordinates.
        internal Rect splashImageRect;

        // Variable to track splash screen dismissal status.
        internal bool dismissed = false;

        // Variable to hold the splash screen object.
        private SplashScreen splash;

        internal Frame rootFrame;


        private DispatcherTimer showWindowTimer;
        private int showWindowTimerNum = 0;

        private void OnShowWindowTimer(object sender, object e)
        {
            showWindowTimerNum += 1;

            if (showWindowTimerNum == 1)
            {
                // Activate/show the window, now that the splash image has rendered
                Window.Current.Activate();
            }
            // aquí hacemos un pequeño descanso antes de mostrar
            // la página principal
            else if (showWindowTimerNum >= 50)
            {
                showWindowTimer.Stop();
                cargarMainPage();
            }
        }

        private void extendedSplashImage_ImageOpened(object sender, RoutedEventArgs e)
        {
            // ImageOpened means the file has been read, but the image hasn't been painted yet.
            // Start a short timer to give the image a chance to render, before showing the window
            // and starting the animation.
            showWindowTimer = new DispatcherTimer();
            showWindowTimer.Interval = TimeSpan.FromMilliseconds(50);
            showWindowTimer.Tick += OnShowWindowTimer;
            showWindowTimer.Start();
        }

        // Position the extended splash screen image in the same location as the system splash screen image.
        private void PositionImage()
        {
            extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X);
            extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);

            extendedSplashImage.Height = splashImageRect.Height;
            extendedSplashImage.Width = splashImageRect.Width;
        }

        private void ExtendedSplash_OnResize(object sender, WindowSizeChangedEventArgs e)
        {
            // Safely update the extended splash screen image coordinates.
            // This function will be fired in response to snapping, unsnapping, rotation, etc...
            if (splash != null)
            {
                // Update the coordinates of the splash screen image.
                splashImageRect = splash.ImageLocation;
                PositionImage();
            }
        }

        private void cargarMainPage()
        {
            // Navigate to MainPage
            rootFrame.Navigate(typeof(MainPage));

            // Set extended splash info on Main Page
            //(rootFrame.Content as MainPage).SetExtendedSplashInfo(splashImageRect, dismissed);

            // Place the frame in the currrent window
            Window.Current.Content = rootFrame;
        }

        // Include code to be executed when the system has transitioned 
        // from the splash screen to the extended splash screen (application's first view).
        private void DismissedEventHandler(SplashScreen sender, object e)
        {
            dismissed = true;

            // Navigate away from the app's extended splash screen after completing setup operations here...
            // This sample navigates away from the extended splash screen when the "Learn More" button is clicked.
        }  
    }
}

 

Ahora sólo falta modificar el código de App.xaml, concretamente el método OnLaunched para que muestre nuestra página de inicio en lugar de MainPage (desde el código de ExtendedSplash nos encargamos de mostrar esa página cuando se ha terminado de mostrar.

 

Aquí tienes el código de VB y el de C# del método OnLaunched de la clase App:

Visual Basic:

Protected Overrides Sub OnLaunched(args As Windows.ApplicationModel.Activation.LaunchActivatedEventArgs)

    ' Para usar el SplashScreen personalizado                   (07/Ene/13)
    If args.PreviousExecutionState <> ApplicationExecutionState.Running Then
        Dim loadState As Boolean = (args.PreviousExecutionState = ApplicationExecutionState.Terminated)
        Dim extendedSplash As ExtendedSplash = New ExtendedSplash(args.SplashScreen, loadState)
        Window.Current.Content = extendedSplash

        ' ExtendedSplash will activate the window when its initial content has been painted.

        ' Salir
        Exit Sub
    End If


    Dim rootFrame As Frame = TryCast(Window.Current.Content, Frame)

    ' Do not repeat app initialization when the Window already has content,
    ' just ensure that the window is active

    If rootFrame Is Nothing Then
        ' Create a Frame to act as the navigation context and navigate to the first page
        rootFrame = New Frame()
        If args.PreviousExecutionState = ApplicationExecutionState.Terminated Then
            ' TODO: Load state from previously suspended application
        End If
        ' Place the frame in the current Window
        Window.Current.Content = rootFrame
    End If
    If rootFrame.Content Is Nothing Then
        ' When the navigation stack isn't restored navigate to the first page,
        ' configuring the new page by passing required information as a navigation
        ' parameter
        If Not rootFrame.Navigate(GetType(MainPage), args.Arguments) Then
            Throw New Exception("Failed to create initial page")
        End If
    End If

    ' Ensure the current window is active
    Window.Current.Activate()
End Sub

 

 

C#:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    // Para usar el SplashScreen personalizado              (07/Ene/13)
    if (args.PreviousExecutionState != ApplicationExecutionState.Running)
    {
        bool loadState = (args.PreviousExecutionState == ApplicationExecutionState.Terminated);
        ExtendedSplash extendedSplash = new ExtendedSplash(args.SplashScreen, loadState);
        Window.Current.Content = extendedSplash;

        // ExtendedSplash will activate the window when its initial content has been painted.

        // Salir
        return;
    }
    

    Frame rootFrame = Window.Current.Content as Frame;

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == null)
    {
        // Create a Frame to act as the navigation context and navigate to the first page
        rootFrame = new Frame();

        if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            //TODO: Load state from previously suspended application
        }

        // Place the frame in the current Window
        Window.Current.Content = rootFrame;
    }

    if (rootFrame.Content == null)
    {
        // When the navigation stack isn't restored navigate to the first page,
        // configuring the new page by passing required information as a navigation
        // parameter
        if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))
        {
            throw new Exception("Failed to create initial page");
        }
    }
    // Ensure the current window is active
    Window.Current.Activate();
}

 

Ya solo quedaría hacer algo en MainPage, pero ahí haz lo que quieras, ya que no hace falta añadir ningún código para esto de mostrar la SplashScreen. Es decir, en esa página añade las cosas que tu aplicación tendrá que hacer.

Y si en lugar de usar MainPage utilizas cualquiera de las otras páginas usadas en los ejemplos de Visual Studio, acuérdate de cambiar el nombre de esa página por la que corresponda en el método que te acabo de mostrar de la clase App y también en el método cargarMainPage de ExtendedSplash.

 

Espero que te sirva para personalizar mejor tus aplicaciones para la Tienda de Windows 😉

 

Nos vemos.

Guillermo

Con la que está cayendo (19 enero)

 

Pues eso… ¡vaya agüilla que está cayendo? y mañana está prevista la subida a la Cuesta del Cielo… ¿Lloverá mañana? Viendo lo que hay tiene toda la pinta que sí, y si miramos el tiempo en Bing (captura 1) eso es lo que predice… pero si nos vamos a eltiempo.es (captura 2) puede que mañana haya una tregua… y si no llueve cuando salgamos a las 8 de la mañana, puede que se equivoque y ganen los de Bing y nos vuelva a nevar… a ver…

 

el tiempo en Nerja 19ene13 bing
Captura 1. El tiempo para Nerja según Bing en Windows 8.

 

El Tiempo en Nerja 19ene13 eltiempo
Captura 2. La previsión para Nerja de eltiempo.es

 

De todas formas el programilla ese de la captura 1 no sé exactamente qué sitio web utiliza, tiene toda la pinta que sea cualquiera de los dos que muestra (AccuWeather -captura 4- y Foreca -captura 5-) pero si buscas por "el tiempo Bing" te muestra (entre otras cosas) la página de Yahoo! clima (es que se ve que esta gente de Bing y Yahoo hacen buenas migas, como las que pegan hoy con la lluvia esta), y en la captura 3 tienes ese tiempo según Yahoo! clima para Nerja, eso sí los grados en Farenheit que es como nosotros los medimos.

 

el tiempo en Nerja 19ene13 Yahoo  Clima
Captura 3. El tiempo en Nerja según Yahoo! clima

 

el tiempo en nerja 19ene13 AccuWeather
Captura 4. El tiempo en Nerja según AccuWeather

 

el tiempo en nerja 19ene13 foreca
Captura 5. El tiempo en Nerja según Foreca

 

A ver qué ocurre mañana…

 

Nos vemos.
Guillermo

Ejemplo sencillo de notificaciones (toast) para Windows Store

 

Pues eso… que aunque aún no son horas de toastar nada, pero te voy a poner un par de ejemplos (o uno solo) de cómo mostrar las notificaciones del sistema (toast notifications), que no son otra cosa que los mensajes (o notificaciones) que aparecen en los laterales de la parte superior de la pantalla de Windows (ver la figura 1).

 

toast01
Figura 1.

 

En principio este tipo de notificaciones están pensadas para eso, notificar al usuario de algo en un momento concreto (ahora te explico esto), pero sobre todo, que el usuario se entere de que eso está ocurriendo (lo están avisando), así que… este tipo de notificaciones se mostrarán siempre encima de lo que haya en ese momento en la pantalla… y cuando digo pantalla me refiero a la pantalla tanto de inicio de Windows 8 como a la "pantalla del escritorio".

 

Lo del par de ejemplos que te comentaba antes es porque hay dos formas de notificar (o mostrar las notificaciones). Una es de forma inmediata, es decir: ¡ya!. La otra es para que se muestre en el momento que indiquemos, ya sean unos segundos después o más tiempo… no sé exactamente cuanto tiempo, pero incluso días y meses después. La tercera (sí, ya se que te dije que había dos, pero…) es una especie de variación de la segunda, ya que también se puede indicar la periodicidad de dicha notificación (si se repite, etc.)

Es decir, que hay muchas posibilidades de usar las notificaciones del sistema (o toast notifications), así que, si además de lo que te explique aquí quieres saber más: Introducción a las notificaciones del sistema (Toast notification overview)

 

Lo primero que debes saber es que esto es para usarlo en las aplicaciones de Windows Store y que en el manifiesto de la aplicación tienes que indicar que quieres usar este tipo de notificaciones.

Abre el fichero Package.appxmanifest y en la primera ficha (Application UI) en la lista de las imágenes busca Badge Logo y selecciónala, en la parte de la derecha tendrás las opciones de notificaciones (notifications) en la lista Toast capable selecciona Yes tal como puedes ver en la figura 2.
De no hacerlo, las notificaciones simplemente ¡¡¡ NO APARECERÁN !!!

 

toast03
Figura 2

 

Una vez que tenemos esto, vamos a ver el código (en principio de Visual Basic, ya también el de C# o lo pongo más tarde o te pongo un enlace a Pastebin para cuando esté listo), de todas formas, los que usáis C# no os podéis quejar mucho, ya que la mayoría de los ejemplos de la documentación y otros sitios web están en C#, algo que no es tan habitual para los que prefieren usar Visual Basic, en fin…

 

Los pasos a seguir:

Crea un proyecto para la tienda de Windows (yo he creado el m´s básico).

Abre el fichero del manifiesto de la aplicación (Package.appxmanifest) y selecciona Yes en Toast capable (ver figura 2).

En MainPage.xaml vamos a crear una barra de aplicación (AppBar) con tres botones.
El diseño de esos botones los tomaremos del fichero StandardStyles.xaml (en la carpeta Common), pero como quiero cambiarles el texto para que me lo muestre en castellano, los he copiado y pegado en los recursos de la página (cambiándoles el nombre para que no haya conflictos, aunque en esta caso no los habría ya que los botones del fichero StandarStyles suelen estar comentados, al menos en la plantilla de las aplicaciones básicas.

Esos tres botones usarán distintos tipos de notificaciones, con idea de que sepas manejarte con varias de las posibilidades que tiene esto de los "toast notifications".

El primer botón envía una notificación inmediata usando un periodo largo, es decir, la notificación tardará más de lo habitual en quitarse, también está desactivado el audio (es una notificación silenciosa y de larga duración, jeje).

Al pulsar en el segundo botón mostrará una notificación a los 3 segundos y esta si que será con sonido y de duración normal.

El tercer botón se notificará de forma inmediata y otra más a los 10 segundos, ambas serán de larga duración y con sonido.

 

Aquí tienes una captura en pleno funcionamiento:

 

toast05
Figura 3. La aplicación en funcionamiento

 

Este es el código XAML completo, con la definición de los estilos de los tres botones.

 

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

    <Page.Resources>
        <Style x:Key="PlayEsAppBarButtonStyle" TargetType="ButtonBase" 
               BasedOn="{StaticResource AppBarButtonStyle}">
            <Setter Property="AutomationProperties.AutomationId" Value="PlayAppBarButton"/>
            <Setter Property="AutomationProperties.Name" Value="Inmediato"/>
            <Setter Property="Content" Value="&#xE102;"/>
        </Style>

        <Style x:Key="HelpEsAppBarButtonStyle" TargetType="ButtonBase" 
               BasedOn="{StaticResource AppBarButtonStyle}">
            <Setter Property="AutomationProperties.AutomationId" Value="HelpAppBarButton"/>
            <Setter Property="AutomationProperties.Name" Value="Ayuda"/>
            <Setter Property="Content" Value="&#xE11B;"/>
        </Style>
        <Style x:Key="ClockEsAppBarButtonStyle" TargetType="ButtonBase" 
               BasedOn="{StaticResource AppBarButtonStyle}">
            <Setter Property="AutomationProperties.AutomationId" Value="ClockAppBarButton"/>
            <Setter Property="AutomationProperties.Name" Value="Programado"/>
            <Setter Property="Content" Value="&#xE121;"/>
        </Style>
    </Page.Resources>
    
    <Page.BottomAppBar>
        <AppBar x:Name="bottomAppBar1" Padding="10,0,10,0">
            <Grid>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                    <Button Style="{StaticResource PlayEsAppBarButtonStyle}" 
                            Click="ButtonPlay_Click" />
                    <Button Style="{StaticResource ClockEsAppBarButtonStyle}" 
                            Click="ButtonClock_Click" />
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                    <Button Style="{StaticResource HelpEsAppBarButtonStyle}" 
                            Click="ButtonHelp_Click" />
                </StackPanel>
                
            </Grid>
        </AppBar>
    </Page.BottomAppBar>
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="80" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <!-- El título de la página -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock x:Name="pageTitle" Grid.Column="1" Text="Prueba de toast notifications" 
                       IsHitTestVisible="false" 
                       Style="{StaticResource PageHeaderTextStyle}" />
            <Image x:Name="imgLogo" Grid.Column="2" Margin="10" 
                   Source="///Assets/SmallLogo.png" Stretch="Uniform" />
        </Grid>

    </Grid>
</Page>

 

Y este es el código de los tres botones Visual Basic:

Primero te pongo las dos importaciones que hay que añadir:

 

Imports Windows.UI.Notifications
Imports Windows.Data.Xml.Dom

 

Y este es el código de los tres botones, las explicaciones están en los comentarios.

 

Private Sub ButtonPlay_Click(sender As Object, e As RoutedEventArgs)

    ' La plantilla a usar, esta Text03 es:
    ' un texto de cabecera que puede ocupar dos líneas y una línea de texto normal
    Dim toastTemplate As ToastTemplateType = ToastTemplateType.ToastText03
    ' Asignamos el template a un documento Xml
    Dim toastXml As XmlDocument = ToastNotificationManager.GetTemplateContent(toastTemplate)

    ' El texto para el primero elemento de la pantilla
    Dim toastTextElements As XmlNodeList = toastXml.GetElementsByTagName("text")
    toastTextElements(0).AppendChild(toastXml.CreateTextNode("Cargando ..."))

    ' Si queremos que la duración sea larga
    ' Puede ser corta o larga, corta es la predeterminada
    Dim toastNode As IXmlNode = toastXml.SelectSingleNode("/toast")
    TryCast(toastNode, XmlElement).SetAttribute("duration", "long")

    ' Si queremos quitar el sonido
    ' (o indicar alguno en particular)
    ' tenemos que usar el elemento "audio"
    'Dim toastNode As IXmlNode = toastXml.SelectSingleNode("/toast")
    Dim audio As XmlElement = toastXml.CreateElement("audio")
    audio.SetAttribute("silent", "true")
    toastNode.AppendChild(audio)


    Dim toast As New ToastNotification(toastXml)
    ToastNotificationManager.CreateToastNotifier().Show(toast)
End Sub

Private Sub ButtonClock_Click(sender As Object, e As RoutedEventArgs)

    ' La plantilla a usar, esta Text03 es:
    ' un texto de cabecera que puede ocupar dos líneas y una línea de texto normal
    Dim toastTemplate As ToastTemplateType = ToastTemplateType.ToastText03
    ' Asignamos el template a un documento Xml
    Dim toastXml As XmlDocument = ToastNotificationManager.GetTemplateContent(toastTemplate)

    ' El texto para el primero elemento de la pantilla
    Dim toastTextElements As XmlNodeList = toastXml.GetElementsByTagName("text")
    toastTextElements(0).AppendChild(
        toastXml.CreateTextNode("A los 3 segundos después de haber pulsado en el botón."))
    toastTextElements(1).AppendChild(
        toastXml.CreateTextNode("Segundo texto."))

    ' Esto es para indicar que esta notificación se hará en el momento indicado
    Dim dueTime As DateTime = DateTime.Now.AddSeconds(3)
    Dim scheduledToast As New ScheduledToastNotification(toastXml, dueTime)

    ToastNotificationManager.CreateToastNotifier().AddToSchedule(scheduledToast)

End Sub

Private Sub ButtonHelp_Click(sender As Object, e As RoutedEventArgs)
    ' La plantilla a usar, esta Text02 es:
    ' un texto de cabecera y un texto normal que puede ocupar dos líneas
    Dim toastTemplate As ToastTemplateType = ToastTemplateType.ToastText02
    ' Asignamos el template a un documento Xml
    Dim toastXml As XmlDocument = ToastNotificationManager.GetTemplateContent(toastTemplate)

    ' El texto para el primero elemento de la pantilla
    Dim toastTextElements As XmlNodeList = toastXml.GetElementsByTagName("text")
    toastTextElements(0).AppendChild(
        toastXml.CreateTextNode("Esto se mostrará durante más tiempo ..."))
    toastTextElements(1).AppendChild(
        toastXml.CreateTextNode("Siempre puedes cerrar las notificaciones en la X superior."))

    ' Si queremos que la duración sea larga
    ' Puede ser corta o larga, corta es la predeterminada
    Dim toastNode As IXmlNode = toastXml.SelectSingleNode("/toast")
    TryCast(toastNode, XmlElement).SetAttribute("duration", "long")

    ' Esto es para indicar que esta notificación se hará en el momento indicado
    Dim dueTime As DateTime = DateTime.Now.AddSeconds(10)
    Dim scheduledToast As New ScheduledToastNotification(toastXml, dueTime)

    ToastNotificationManager.CreateToastNotifier().AddToSchedule(scheduledToast)

    Dim toast As New ToastNotification(toastXml)
    ToastNotificationManager.CreateToastNotifier().Show(toast)

 

Ese es el código para C# (no he tardado tanto, ¿verdad? son las 06.35 y lo publiqué a eso de las 6.05)

 

Añade estas dos importaciones:

 

using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;

 

private void ButtonPlay_Click(object sender, RoutedEventArgs e)
{
    // La plantilla a usar, esta Text03 es:
    // un texto de cabecera que puede ocupar dos líneas y una línea de texto normal
    ToastTemplateType toastTemplate = ToastTemplateType.ToastText03;

    // Asignamos el template a un documento Xml
    XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

    // El texto para el primer elemento de la pantilla
    XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
    toastTextElements[0].AppendChild(toastXml.CreateTextNode("Cargando ..."));

    // Si queremos que la duración sea larga
    // Puede ser corta o larga, corta es la predeterminada
    IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
    ((XmlElement)toastNode).SetAttribute("duration", "long");

    // Si queremos quitar el sonido
    // (o indicar alguno en particular)
    // tenemos que usar el elemento "audio"
    // IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
    XmlElement audio = toastXml.CreateElement("audio");
    audio.SetAttribute("silent", "true");
    toastNode.AppendChild(audio);

    ToastNotification toast = new ToastNotification(toastXml);
    ToastNotificationManager.CreateToastNotifier().Show(toast);
}

private void ButtonClock_Click(object sender, RoutedEventArgs e)
{
    // La plantilla a usar, esta Text03 es:
    // un texto de cabecera que puede ocupar dos líneas y una línea de texto normal
    ToastTemplateType toastTemplate = ToastTemplateType.ToastText03;

    // Asignamos el template a un documento Xml
    XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

    // El texto para el primer elemento de la pantilla
    XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
    toastTextElements[0].AppendChild(
        toastXml.CreateTextNode("A los 3 segundos después de haber pulsado en el botón."));
    toastTextElements[1].AppendChild(
        toastXml.CreateTextNode("Segundo texto."));

    // Esto es para indicar que esta notificación se hará en el momento indicado
    DateTime dueTime = DateTime.Now.AddSeconds(3);
    ScheduledToastNotification scheduledToast = new ScheduledToastNotification(toastXml, dueTime);

    ToastNotificationManager.CreateToastNotifier().AddToSchedule(scheduledToast);
}

private void ButtonHelp_Click(object sender, RoutedEventArgs e)
{
    // La plantilla a usar, esta Text02 es:
    // un texto de cabecera y un texto normal que puede ocupar dos líneas
    ToastTemplateType toastTemplate = ToastTemplateType.ToastText02;
    // Asignamos el template a un documento Xml
    XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);

    // El texto para el primero elemento de la pantilla
    XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
    toastTextElements[0].AppendChild(
        toastXml.CreateTextNode("Esto se mostrará durante más tiempo ..."));
    toastTextElements[1].AppendChild(
        toastXml.CreateTextNode("Siempre puedes cerrar las notificaciones en la X superior."));

    // Si queremos que la duración sea larga
    // Puede ser corta o larga, corta es la predeterminada
    IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
    (toastNode as XmlElement).SetAttribute("duration", "long");

    // Esto es para indicar que esta notificación se hará en el momento indicado
    DateTime dueTime = DateTime.Now.AddSeconds(10);
    ScheduledToastNotification scheduledToast = new ScheduledToastNotification(toastXml, dueTime);

    ToastNotificationManager.CreateToastNotifier().AddToSchedule(scheduledToast);

    ToastNotification toast = new ToastNotification(toastXml);
    ToastNotificationManager.CreateToastNotifier().Show(toast);
}

 

 

Como comentario adicional, decirte que podemos "detener" una notificación si tenemos a nuestra disposición el objeto con la que se creó, ya que para detenerla tenemos que usar el método Hide de la función compartida CreateToastNotifier. A ese método Hide le tenemos que pasar una referencia al objeto que queremos detener. Yo esto lo he usado en la aplicación que he mandado a la tienda de Windows, en la que muestro la notificación mientras se carga una página web en el control WebView y la oculto cuando dicha página se ha terminado de cargar o lo que es lo mismo, intercepto el evento LoadComplete del control WebView, y ahí es donde quito la notificación.

Como es natural, el objeto "toast" usado para esa notificación no puede estar definido dentro de un sub, ya que así no sería accesible desde otra parte del código. Por tanto, en ese caso, el objeto toast usado para poder ocultarlo cuando queramos, lo tendríamos que definir fuera de cualquier método.

 

Espero que todo esto te sea de utilidad y para los que prefieren el C#, dadme unos minutos a que cree el proyecto en ese lenguaje y convierta el código, lo tacho porque ya está publicado.

 

Nos vemos.

Guillermo

Consejos para publicar aplicaciones en la tienda de Windows

 

Pues eso… que ahora que lo tengo fresco te voy a explicar las cosas que debes tener preparadas para cuando quieras publicar una aplicación en la tienda de Windows (Windows Store).
Lo de que lo tengo fresco es porque acabo de enviar a "certificar" las dos versiones de mi segunda aplicación para la tienda de Windows: Lector Rss para Windows 8.

 

Primero de todo debes crear la aplicación que quieres publicar en la tienda de Windows, este requisito es… vamos que si no tienes algo que publicar, pues…

En el manifiesto de la aplicación (accesible desde Visual Studio) debes indicar ciertas características de la aplicación, como qué iconos (imágenes) utiliza y qué requisitos requiere, por ejemplo, acceso a internet, a la cámara, etc.

Los iconos o imágenes de la aplicación que deben incluirse son los que se añaden si creamos la aplicación usando una de las plantillas de Visual Studio, a saber:

  • Logo (150×150)
  • Small Logo (30×30)
  • Splash Screen (620×300)
  • Store Logo (50×50)

Opcionalmente puedes indicar otros tamaños (en el manifiesto te indica qué tamaños debes utilizar) así como otros dos más: Badge Logo (24×24) y Wide Logo (310×150).
Todos ellos en formato PNG (Portable Network Graphics).

Logo y Wide Logo son las imágenes utilizadas en el inicio de Windows, si agregas WideLogo los usuarios podrán mostrar el icono de tu aplicación en modo grande, si no, sólo en el tamaño cuadrado de Logo.

Para saber más de estos logos: Elegir las imágenes de tu aplicación.

 

consejos 01

 

En la pestaña "Capabilities" (capacidades) del manifiesto de la aplicación debes indicar qué va a hacer tu aplicación en esos temas, si algunos de ellos es aplicable a las características de tu aplicación, entonces debes seleccionarlas.
Un error común (según dicen esta gente de la tienda de Windows) es acceder a Internet sin marcar la opción Internet (Client), que por cierto es la opción que viene seleccionada de forma predeterminada. En esos casos, es fácil que te rechacen la aplicación.

 

consejos 02
Figura 2.

 

Una vez que tienes tu aplicación creada y tu cuenta de la tienda de Windows abierta, desde el propio Visual Studio puedes acceder a ciertas tareas que habitualmente harías desde el panel de tu cuenta de Windows Store o desde el escritorio de tu Windows (por ejemplo para comprobar si la app pasa el proceso de certificación).

Todas esas opciones están en el menú Project > Store (ver la imagen 3).

 

consejos 03

 

Las cosas que debes indicar en la tienda de Windows y que ya deberías tener preparadas son:

La descripción de la aplicación, un par de "características", la dirección web en la que habrá información sobre la aplicación (esto es opcional), una dirección (web) para dar soporte a la aplicación, puede ser una página Web (o blog) o bien un correo electrónico, pero te recomiendo que no uses el correo electrónico, ya que ese correo aparece en los detalles de la tienda de Windows.

Tienes que tener algunas capturas de la aplicación (al menos una) que serán las que se utilicen en la descripción de la tienda de Windows.
El máximo son ocho. En la siguiente imagen puedes ver estas cosas que acabo de comentarte.

 

consejos 04

 

Otra imagen (o imágenes) que puedes preparar (no son obligatorias) pero si no las agregas no podrán "promocionarte" la aplicación. Esas imágenes son las que utilizan en la tienda de Windows para destacar algunas aplicaciones… yo las mando por lo que pueda ocurrir…
Los tamaños son cuatro: 414×180 (el recomendable si sólo quieres mandar una), 414×468, 558×756 y 846×468.
En relación a estas imágenes, recomiendan que no sean simples capturas, si no mas bien imágenes promocionales o con el logo de la aplicación, etc.

 

Y con todo esto listo, tienes más o menos unas cuantas cosas adelantadas, que la primera vez que publiqué una aplicación (hace una semana más o menos) no sabía de estas imágenes y textos a rellenar y… pues eso… que tuve que ponerme a prepararlo todo.

 

Por último comentarte que la aplicación debe estar compilada en modo Release, ya que si la quieres publicar en modo Debug seguro que te la echan para atrás.

 

Nota:
Pues resulta que me han echado para atrás la aplicación que he mandado y que accede a internet (es un lector RSS) y es porque no he puesto la declaración de privacidad, y eso que lo dicen bien claro en la descripción que te muestra cuando pulsas en el enlace que hay en esa pestaña de configuración (ver la figura 2).
Bueno, pues aquí te lo digo y te lo "pego" para que lo sepas:

 

Internet y redes públicas

La funcionalidad internetClient proporciona acceso de salida a Internet y redes públicas a través del firewall. Casi todas las aplicaciones web utilizan esta funcionalidad. La funcionalidad internetClientServer proporciona acceso de entrada y salida a Internet y a redes públicas a través del firewall.

La funcionalidad internetClientServer se utiliza normalmente en escenarios punto a punto (P2P) de aplicaciones que utilizan recurso compartido de archivos y VoIP. La funcionalidad internetClientServer incluye el acceso que proporciona la funcionalidad internetClient, de manera que no tienes que especificar internetClient cuando especificas internetClientServer.

Un requisito de certificación importante es que, si declaras estas funcionalidades, debes incluir un vínculo a tu directiva de privacidad en el panel Configuración. No hacerlo es una de las formas más habituales de impedir que la certificación se produzca.

La página web en la que están las explicaciones de cada una de esas "capabilities" es esta:
Declaraciones de funcionalidades de aplicación (aplicaciones de la Tienda Windows)

 

 

 

Nos vemos.
Guillermo

Enlaces de utilidad:

To Windows or not to Windows

 

Pues eso… un poco de nostalgia comparativa de las primeras versiones de Windows:
Imágenes y textos tomados de: Creating the Windows 8 user experience que al final ha pasado a ser casi un "calco" del original, cuando mi intención era ponerte unas pocas imágenes, en fin…

 

Windows 1

Windows 1 was released in 1985, and it was designed for drastically different scenarios than what people use PCs for today.

3 windows appear in a grid layout. Along bottom of screen are icons for a disk, a calculator, a paint program, and 2 more icons.

The first version of Windows was a rough graphical shell around DOS, intended primarily to be used with the keyboard. A mouse was strictly optional and very few PCs had one.

 

 

Windows 3 and 3.1

The first commercially successful version of Windows was Windows 3, released in 1990. It featured a totally new interface, centered on a new shell called Program Manager for launching, arranging, and switching programs.

Program Manager and File Manager windows float over a series of icons on the desktop

File Manager was the most important new program in Windows 3, used for managing files and drives. This upgrade bet big for the first time on most users having a mouse, and knowing how to use it to click on the colorful, large (for the time) 32×32 icons. Many reviews were critical of the release because to use it effectively required one of those oft-criticized mice.

 

 

Windows 95

Windows 95, released a few years later in August of 1995, included a substantially reinvented user experience. Many of the constructs that are still present in Windows 7 were introduced in this version—the Start menu, taskbar, Explorer, and the desktop—but in very different forms.

Windows Explorer open on the desktop, Start menu shows programs in a flyout menu.

Although we think about these user interface elements as familiar today, at the time, they were radically different from how anyone had used a PC before. The Start button was so undiscoverable that, despite having the word Start right on it, bouncing “<– Click here to begin” text had to be added to the taskbar after early test releases so that people could figure out how to get started using the programs on their PC.

 

Windows XP

Windows XP was released to PC manufacturers on August 24, 2001. It represented another important evolution in the Windows user interface.

My Documents window and Windows Media Player window float over a desktop background image of a green hillside and blue sky. Start button appears at lower left.

By 2001, people were using their PCs more every day. Typing and managing files, which doesn’t require the web, remained a critical percentage of the time people spent using a PC. Yet collecting and consuming information and media—especially music, photos, and videos—was on the verge of becoming mainstream. (Even then, early digital camera sales were still just one quarter of film camera sales, and would not eclipse them for another three years.) People were spending more time on the PC web browsing and doing mail, in addition to the document-focused productivity scenarios around which Windows 95 was developed.

 

Windows Vista

In 2006, Windows Vista substantially changed the visual appearance of Windows, introducing the Aero visual style. Aero gave the appearance of highly-rendered glass, light sources, reflections, and other graphically complex textures in the title bars, taskbar, and other system surfaces. These stylistic elements represented the design sensibilities of the time, reflecting the capabilities of the brand-new digital tools used to create and render them. This style of simulating faux-realistic materials (such as glass or aluminum) on the screen looks dated and cheesy now, but at the time, it was very much en vogue.

Image of Analog Clock gadget on desktop, with a window overlaying it with semi-transparent edges.

Aero was designed to help people focus less on the window chrome itself, and more on the content within the window. It draws the eye away from the title bar and window frames, and towards what is valuable and what an app is about.

And of course, the Start menu changed again, most notably by making it possible to press the Windows key (introduced in Windows 95) and then just start typing to search from anywhere in Windows. (This welcome innovation is one we’ve kept in Windows 8, expanding it to search even within apps.)

Of course, as with every change along the way, some people expressed reservations about the changes.

 

Windows 7

Windows 7 was released in the fall of 2009, and a number of the key aspects of the UI were significantly transformed. While many of these changes centered on an overhaul of the taskbar, significant modifications were also made to the Start menu, windowing, and to the logical organization of files on the PC.

Start button, with IE, Windows Explorer, and Windows Media Player on Taskbar. 3 instances of IE shown above taskbar (activated on hover)

Notably, launching and switching between programs were brought together in the new taskbar. Icons in the taskbar were made bigger and more touchable. The Start menu was changed to focus on launching only the programs you use less frequently, as no program can be pinned to both the taskbar and the Start menu. This marked the start of a transition where we were looking to remove the archaic distinction between starting a program for the first time and returning to a program that was already running. It is interesting to consider how odd it is that we trained ourselves to look one place for a program the first time it is running, and a different place once it is already running.

Windows 7 also was the first mainstream non-phone OS to introduce multitouch support into the base OS. Although tablets on other platforms have followed suit, Windows 7 was the first shipping OS to embrace multitouch in the platform. Along the way, we learned a great deal about the limitations of trying to use touch to navigate Windows when so much of the existing interface, and virtually all of the existing programs, were specifically designed to be used with mouse and keyboard.

Although some people had critical reactions and demanded changes to the user interface, Windows 7 quickly became the most-used OS in the world.

 

Windows 8 user experience

But as we move closer to general availability of Windows 8 and beyond, to a time when all of your favorite apps are available and represented by tiles, suddenly your Start screen will become a personalized dashboard of everything you care about. Your whole computing experience has the potential to be encapsulated in one view. A view that you organize and control.

Start screen with 16 live tiles

Even content from within apps can be pinned to Start: people, mail folders, accounts, websites, books, albums, singers, movies, clients, sports teams, cities, etc. Everything you care about is efficiently available and up-to-date at all times. Tiles are the future and fit the way people look for fresh content in apps and websites.

 

Pues ya está…

Nos vemos.
Guillermo

El misterio de los controles desaparecidos

 

Pues eso… aunque los controles más que desparecidos están o son invisibles…
Y es curioso porque "supuestamente" estoy usando lo mismo en ambas versiones…
Ah.. que no te he explicado de qué va la cosa…

Pues resulta que la primera vez que quise hacer un panel para la configuración me basé en un ejemplo de la documentación en línea: Quickstart: Add app settings, pero al mostrar el código del panel (en el que había solo un ToggleSwitch) dicho control no era visible, pero estaba.

 

La solución

 

En esa misma página hay un enlace a un ejemplo del SDK:

App settings sample. En el que, al menos en el código de C#, hay un panel de configuración (SettingsFlyout.xaml) con un montón de controles (ver la figura 1), y todos ellos son visibles… es decir, están y se puede demostrar.

 

settingsFlyout sdk
Figura 1. El panel de configuración del ejemplo de C# en App settings sample

 

Sin embargo, he copiado esa página en otro proyecto (tanto de VB como de C#) y no hay forma de que se vean los controles, que están, pero no se puede demostrar… y para muestra, la figura 2.

 

settingsFlyout blanco
Figura 2. La misma página usada para la captura de la figura 1 en otro proyecto

 

He mirado los estilos, he comprobado que todo está como en el proyecto original y nada… no hay forma de que se vean dichos controles. Primero pensé que era porque estaba usando Visual Basic y que faltaba algo del código usado en C#, pero no… también lo he probado en un proyecto de C# y tampoco soy capaz de mostrar los controles.
De todas formas, en el ejemplo del SDK sólo he visto que esa página esté en el proyecto de C# pero no en el de Visual Basic… lo mismo es que a ellos les pasó lo mismo… hum… aunque no me sirve de consuelo… no… 🙁

Seguramente será algo simple, pero no doy con la tecla… y lo publico por si por casualidad alguien lo ve y sabe cuál es el problema… porque yo no soy capaz de encontrarlo… en fin…

 

Lo dicho, si sabes cómo solucionarlo, me lo dices.
Gracias.

 

 

 

La solución:

En el fichero App.xaml (en la definición de <Application) añadir lo siguiente:

RequestedTheme="Light"

¡¡¡Y ya se ven los dichosos controles!!!

La inspiración vino al leer el artículo Windows Store App Settings Flyout de Mohamed Mahmoud El-Geish en el que explica cómo hay que diseñar uno de estos paneles y al indicar que el fondo del panel debe ser blanco indica el problema de los colores… y lo de indicar el RequestedTheme.

Después de encontrar esta solución, vi que en mi facebook, Omar del Valle había puesto un enlace en el que explican esto de los temas claros y oscuros (Light y Dark):
Mixing themes in XAML Metro apps.

En fin…

 

 

Nos vemos.
Guillermo