Etiqueta: .NET

Temas relacionados con .NET Framework (todas las versiones)

  • Usar un temporizador en las aplicaciones de Windows store (Visual Basic)

    Pues eso… que estoy probando esto de la creación de aplicaciones para Windows 8 (para la tienda de Windows o Windows store) y quería crear un programa simple que mostrase la fecha y la hora y se fuese actualizando cada segundo…

    Esto en una aplicación de escritorio no es nada complicado… y en una aplicación XAML para la tienda de Windows 8 tampoco lo tendría que ser… el problema es que no encontraba la definición del control Timer (no existe) ni la definición de la clase Timer (definida en System.Timers o en System.Threading) que en una aplicación para Windows store no están definidas.

    Buscando buscando me encontré con varias clases, dos de ellas algo "liantes" de usar (además de que sin ejemplos para Visual Basic), me refiero a las clases definidas en Windows.System.Threading: ThreadPoolTimer (y otra de la que ya ni me acuerdo).

    La cuestión es que también me encontré con la que he usado en este primer ejemplo, esta clase se llama DispatcherTimer y está definida en el espacio de nombres Windows.UI.Xaml, y es más sencilla de utilizar sobre todo para todo lo relacionado con la creación del método de evento, ya que se puede usar WithEvents para la definición de la variable y crear fácilmente dicho método de evento; aunque en este ejemplo usaré AddHandler para indicar cuál es el método de evento (el que se ejecutará cada vez que pase el tiempo indicado en el intervalo), esto lo hago así de "complicado" porque después publicaré el código para los que le gusten usar los puntos y comas, es decir, el código para C#.

     

    El ejemplo es muy simple, tendremos un par de bloques de texto y un botón para iniciar/detener el temporizador.

    Primero te muestro el código XAML del fichero MainPage.xaml y después veremos el código de Visual Basic (cuando lo tenga publicado te pondré el enlace a la versión de C#).

     

    MainPage.xaml:

    <Page
        x:Class="Reloj_Windows_8.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Reloj_Windows_8"
        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}">
            <StackPanel Orientation="Vertical" Margin="10" HorizontalAlignment="Stretch"  VerticalAlignment="Center">
                <TextBlock x:Name="txtHora" Margin="20" Text="19:47:00" TextAlignment="Center" Foreground="Lime" FontWeight="Bold" FontFamily="Consolas" FontSize="72" />
                <TextBlock x:Name="txtFecha" Margin="10" Text="viernes 30 noviembre 2012" TextAlignment="Center" Foreground="Lime" FontWeight="Bold" FontFamily="Consolas" FontSize="36" />
                <StackPanel HorizontalAlignment="Center" Margin="10">
                    <Button x:Name="btnStop" Content="Stop" Margin="20"/>
                </StackPanel>
            </StackPanel>
        </Grid>
    </Page>
    

     

     

    MainPage.xaml.vb:

    Public NotInheritable Class MainPage
        Inherits Page
    
        Private intervalo As Integer = 900
    
        ' La clase DispatcherTimer está definida en el espacio de nombres:
        ' Windows.UI.Xaml
        Private timer1 As DispatcherTimer
    
        ''' <summary>
        ''' Invoked when this page is about to be displayed in a Frame.
        ''' </summary>
        ''' <param name="e">Event data that describes how this page was reached.  The Parameter
        ''' property is typically used to configure the page.</param>
        Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
            actualizarHora()
    
            btnStop.Content = "Start"
            btnStop_Click(btnStop, Nothing)
        End Sub
    
        ''' <summary>
        ''' Asigna la fecha y hora en las cajas de texto
        ''' </summary>
        Private Sub actualizarHora()
            Me.txtHora.Text = DateTime.Now.ToString("HH:mm:ss")
            Me.txtFecha.Text = DateTime.Now.ToString("dddd, dd MMMM yyyy")
        End Sub
    
        ''' <summary>
        ''' Este evento es del temporizador y
        ''' se ejecutará en cada intervalo.
        ''' </summary>
        ''' <remarks>
        ''' Es conveniente no usar un valor muy pequeño para el intervalo
        ''' lo recomendable es un poco menos de 1 segundo (1000 milisegundos)
        ''' En el programa utilizo un valor de 900 milisegundos
        ''' </remarks>
        Private Sub timer1_Tick(sender As Object, e As Object) 'Handles timer1.Tick
            actualizarHora()
        End Sub
    
        ''' <summary>
        ''' Parar o iniciar el temporizador
        ''' </summary>
        ''' <remarks></remarks>
        Private Sub btnStop_Click(sender As Object, e As RoutedEventArgs) Handles btnStop.Click
            If btnStop.Content.ToString = "Stop" Then
                timer1.Stop()
                btnStop.Content = "Start"
            Else
                timer1.Start()
                btnStop.Content = "Stop"
            End If
        End Sub
    
        Public Sub New()
    
            ' This call is required by the designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
    
            ' crear el temporizador
            timer1 = New DispatcherTimer
            AddHandler timer1.Tick, AddressOf timer1_Tick
            ' el intervalo: 900 milisegundos (algo menos de 1 segundo (1seg = 1000ms))
            timer1.Interval = New TimeSpan(0, 0, 0, 0, intervalo)
            'timer1.Start()
        End Sub
    

     

     

    Espero que te sea de utilidad.

    ¡esa es la intención! 😉

     

    Por cierto, esta aplicación la publicaré en el Windows Store y allí la iré actualizando (ya te avisaré cuando esté publicada, si es que la publican, claro).

    Como me gusta que las cosas sean "gratis" el precio será de 0 euros, pero como también sé que hay gente que le gusta colaborar (económicamente) con mi(s) sitio(s) (o conmigo para que siga manteniendo mis sitios), y eso de usar PayPal no les gusta mucho, he pensado que también habrá una versión de pago (algo simbólico, supongo que medio euro o un USD dólar o algo así).

    Ya te avisaré también… ¡que a todos nos hace falta seguir manteniéndonos! jeje

    Nos vemos.

    Guillermo

     

    Enlaces a los otros artículos de este "paso a paso":

    1. Usar un temporizador en las aplicaciones de Windows store (Visual Basic)
    2. Usar un temporizador en las aplicaciones de Windows store (C#)
    3. Pon una AppBar en tu aplicación de Windows Store
    4. Acceder a los recursos de una aplicación de Windows Store desde código (vb, c#, xaml)
    5. Actualizar el icono (tile) de una aplicación de Windows Store (cada minuto)
    6. Saber cuando la aplicación está en modo Snapped y actuar en consecuencia

  • Asignar el foco a un control al cargar una página web aspx (ampliación y recapitulación)

    Pues eso… que lo de "ampliación" es por no poner "revisited" o algo similar que eso ya está muy visto, jeje y lo de "recapitulación" por el chasco/descubrimiento/formas diferentes de funcionar con el que me he encontrado al hacer pruebas en VB y en C#, ya verás, ya…

    Pero en realidad esto es una aclaración o más bien un añadido (o ampliación) del otro artículo que publiqué el pasado 11 de octubre sobre este mismo tema, es decir, cómo asignar el foco a un control al cargar una página web aspx, en ese caso el código era con Visual Basic .NET pero lo importante no era el código si no lo explicado, es decir la forma de conseguir eso que indica el título.

    La aclaración es porque en ese ejemplo el código y el diseño está todo en un mismo fichero (archivo) en lugar de tener el código por un lado y el diseño por otro, que es como el Visual Studio se empeña que lo hagamos, aunque en mi caso particular me gusta más (o prefiero) tener todo junto, ya que así es más fácil de actualizar la página en concreto, al menos para mí, que todo puede ser que a tí te venga mejor compilar el código y publicarlo cada vez que hagas una modificación por pequeña que sea… ¡hay gustos para todo! 😉

     

    Vamos a lo que vamos.

    Si utilizas el código por separado del diseño de la página web entonces no es necesario asignar un valor true a la propiedad AutoEventWireup, ese valor verdadero sólo debes asignarlo si el código a usar está "incrustado" en la página web ASPX y no en un fichero separado (el cual hay que compilar y publicar en el sitio web).

     

    La forma de indicar si tienes el código "incrustado" o por separado es usando (lo que se llama "code behind"), esto lo puedes indicar al crear un nuevo fichero en el proyecto web tal como puedes ver en la figura 1 en la que he resaltado la parte que le indica a Visual Studio si quieres usar el código en un fichero separado o no (en este ejemplo SI se usa por separado).

    orden_tabulacion_fig1
    Figura 1. Indicar si queremos el código por separado o no

     

    Esto creará dos ficheros uno con la extensión .aspx (el diseño de la página web) y otro con la extensión del lenguaje usado, en este ejemplo al indicar que el código es de C# la extensión del fichero de código es: .aspx.cs.

    En este caso, el código de "enfoque" del control que queremos que sea el primero en recibir el foco lo pondremos dentro del evento Page_Load tal como podemos ver en los dos listados (el del diseñador y el código).
    (Ver el comentario de la nota).

     

    Listado 1 (el código del diseñador .aspx):

     

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Default3 - con el código por separado (en C#)</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
            <asp:TextBox ID="TextBox1" runat="server">uno</asp:TextBox><br />
            <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
            <asp:TextBox ID="TextBox2" runat="server">dos</asp:TextBox><br />
            <asp:Label ID="Label3" runat="server" Text="Label"></asp:Label>
            <asp:TextBox ID="TextBox3" runat="server">tres</asp:TextBox><br />
            <asp:Button ID="Button1" runat="server" Text="Button" />    
        </div>
        </form>
    </body>
    </html>

     

    Listado 2 (el código de C# .aspx.cs):

     

    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    public partial class Default3 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            this.TextBox1.Focus();
        }
    

     

     

    Nota:

    Es curioso, pero al hacer la prueba con C# para "demostrar" todo esto que estoy explicando, si no uso un valor verdadero (true) en la propiedad AutoEventWireup de la página de C# no se ejecuta ese código del evento Page_Load, sin embargo (de ahí lo de curioso) en el código de Visual Basic da igual el valor que tenga esa propiedad… ¡jum!

     

     

    Conclusión:

    Que no tengo ni idea de por qué pasa esto con una página de C#… así que… sigue usando AutoEventWireup = "true" y así seguro que siempre te funciona…

    Como te he dicho antes (en la nota) en Visual Basic .NET si va bien, uses true o false en AutoEventWireup, eso sí, siempre que el código esté por separado, si el código está en la misma página, si hay que indicar el valor true.

    En cualquier caso, lo cierto es que al añadir la página de C# el valor de la propiedad AutoEventWireup tiene el valor true, mientras que en Visual Basic es false.

    Todo esto (no solo que el valor sea verdadero/falso) es otra demostración de que a los de Visual Basic nos tratan de forma diferente…

    En fin…

     

    Espero que te sea de utilidad.

     

    Nos vemos.

    Guillermo

  • Asignar el foco a un control al cargar una página web aspx

    Pues eso… que con la cabeza que tengo (se me olvidan las cosas o lo mismo mi disco duro ya está lleno, a saber) me he decidido a publicar este "truco" para ASP.NET usando páginas web ASPX, ya que hoy lo he necesitado y no me acordaba cómo había que hacerlo… o casi… ahora te explico el casi.

     

    Asignar el foco a un control de una página web ASPX al cargarla

    La idea es que hay que "darle el foco" al control en cuestión y aquí no vale eso de asignar un valor cero (0) a la propiedad TabIndex del control, que es lo que haríamos en una aplicación de escritorio (y casi me atrevería a decir que a una de XAML).

    Otra cosa que se te puede ocurrir es asignar el foco al cargar "el formulario" (en este caso la página web), y por ahí iríamos bien… pero en el caso de las páginas web ASPX el evento Load (en realidad Page_Load) no se produce o al menos no podemos interceptarlo salvo que indiquemos en la directiva @Page que queremos hacerlo, esto lo conseguimos asignando un valor "true" a la propiedad AutoEventWireup (el valor predeterminado o por defecto, es "false").

     

    Y uniendo todo lo dicho tendríamos algo así:

    <%@ Page Language="vb" AutoEventWireup="true" Strict="true" %>
    
    <!DOCTYPE html>
    <script runat="server">
    
        ' Para que se ponga el foco en el control indicado
        ' en @Page hay que indicar AutoEventWireup="true"
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
            If IsPostBack = False Then
                txtTotal.Focus()
            End If
        End Sub
        
    </script>
    
    

     

    Espero que te pueda ser útil

    Nos vemos.

    Guillermo

    P.S.

    Nota del 28/Oct/2012:

    Mira esta actualización que seguro que te interesa también:

    Asignar el foco a un control al cargar una página web aspx (ampliación y recapitulación)