Etiqueta: C#Sharp

Temas relacionados con C#

  • Detectar pulsación de teclas en el formulario (y controles)

    Pues eso… esto viene a raíz de una consulta sobre cómo detectar la pulsación de teclas en los formularios de Windows Forms, es decir, saber qué tecla se ha pulsado aunque ya se esté detectando en cajas de texto u otros controles.

    En los controles no hay problemas para detectarlo, ya que solo tendremos que escribir código en los eventos de pulsación de teclas: KeyPress, KeyDown o KeyUp del control y asunto arreglado.

    Pero cuando se trata de detectar esas pulsaciones a nivel de formulario, es decir, independientemente de qué control tenga el foco, también podemos usar esos tres métodos de evento en el formulario, pero antes debemos indicarle al runtime de .NET que queremos detectar esas pulsaciones de teclas.

    Para ello debemos asignar un valor True a la propiedad KeyPreview del formulario.

    Distinguir la pulsación en mayúsculas de minúsculas (o no)

    Si queremos detectar la pulsación de teclas sin que nos importe si es una tecla mayúscula o minúscula lo mejor es hacerlo en cualquiera de los eventos KeyDown o KeyUp, ya que en esos eventos además de la tecla pulsada se puede saber si también se pulsa la tecla Shift (cambio de mayúsculas).

    En caso de querer detectar la pulsación de letras en el evento KeyPress tendremos que hacer una doble comprobación, una para la letra en mayúscula y otra para saber si es minúscula.

    Nota del 18/Sep/2020:
    Si quieres detectar la pulsación con la tecla Control (CTRL) o Shift o Alt, es recomendable hacer algo como el código que te indico a continuación.

    Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs)
        If e.KeyCode = Keys.F3 Then
            e.Handled = True
            Buscar()
        ElseIf e.Control Then
            If e.KeyCode = Keys.F Then
                e.Handled = True
                esCtrlF = True
                Buscar()
            ElseIf e.KeyCode = Keys.H Then
                e.Handled = True
                Reemplazar()
            End If
        End If
    End Sub
    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.F3)
        {
            e.Handled = true;
            Buscar();
        }
        else if (e.Control)
        {
            if (e.KeyCode == Keys.F)
            {
                e.Handled = true;
                esCtrlF = true;
                Buscar();
            }
            else if (e.KeyCode == Keys.H)
            {
                e.Handled = true;
                Reemplazar();
            }
        }
    }

     

    El orden de pulsación de teclas (en controles y formulario)

    Debido a que podemos usar los tres eventos comentados al principio, lo mismo te interesa saber en qué orden se procesan los eventos.

    El orden es el siguiente:

    1. KeyDown
    2. KeyPress
    3. KeyUp

    Lista 1. Orden en que se procesan los eventos de pulsación de teclas

    Y si estamos comprobando en el formulario además de en los controles, el orden global será el siguiente:

    1. KeyDown del formulario
    2. KeyDown del control
    3. KeyPress del formulario
    4. KeyPress del control
    5. KeyUp del formulario
    6. KeyUp del control

    Lista 2. Orden en que se procesan los eventos de pulsación de teclas cuando se comprueba también en el formulario además de en los controles

    Es decir, el mismo orden que en la lista 1, pero empezando siempre por el formulario y después en el control.

    Veamos un poco de código de ejemplo

    Para esta prueba creamos un proyecto nuevo y al formulario le añadimos los controles mostrados en la figura 1.

    pulsar teclas en formulario
    Figura 1. El formulario de prueba en modo de diseño

    Creamos los eventos KeyDown, KeyPress y KeyUp tanto en el formulario como en las cajas de texto. Para este ejemplo, solo he puesto código para detectar la pulsación en la primera caja de textos (textBox1) y en el formulario (recuerda asignar un valor verdadero a la propiedad KeyPreview del formulario).

    En este código (tanto para Visual Basic como para C#) detectamos la pulsación de las teclas S y W tanto en el textBox1 con en el propio formulario. Están contemplados los tres eventos comentados y en la caja de textos (textBox3) de la parte inferior, a la que he asignado un valor True a la propiedad MultiLine, así como el valor Vertical a la propiedad ScrollBars. con idea de que nos permita desplazarnos por el contenido y veamos la secuencia de pulsación de teclas.

    Nota:
    Más abajo tienes un enlace al proyecto del código de ejemplo.

    Código de ejemplo para C#

    Nota:
    Recuerda asignar estos métodos a los eventos correspondientes.

    // El orden "global" de pulsación es:
    // KeyDown en formulario
    // KeyDown en control
    // KeyPress en formulario
    // KeyPress en control
    // KeyUp en formulario
    // KeyUp en control
    
    // para que detecte las pulsaciones en el formulario 
    // hay que asignar un valor True a la propiedad KeyPreview del formulario
    
    // en KeyDown no diferencia entre mayúsculas y minúsculas
    // en KeyPess si distingue la diferencia
    
    private void Form1_KeyPress(object sender, KeyPressEventArgs e)
    {
        switch (e.KeyChar)
        {
            case (char)Keys.W: // mayúsculas
            case (char)(Keys.W + 32): // minúsculas
                label3.Text += "\nTecla W en el formulario";
                textBox3.Text += "\r\nTecla W en el formulario (KeyPress)";
                break;
            case (char)Keys.S:
            case (char)(Keys.S + 32): // minúsculas
                label3.Text += "\nTecla S en el formulario";
                break;
        }
    
    }
    
    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        // da igual mayúsculas que minúsculas
        switch (e.KeyCode)
        {
            case Keys.S:
                label3.Text = "Tecla S en el formulario (KeyDown)";
                break;
            case Keys.W:
                label3.Text = "Tecla W en el formulario (KeyDown)";
                textBox3.Text += "\r\nTecla W en el formulario (KeyDown)";
                break;
        }
    }
    
    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        switch (e.KeyValue)
        {
            case (char)Keys.S:
                label3.Text = "Tecla S en el formulario (KeyUp)";
                break;
            case (char)Keys.W:
                label3.Text = "Tecla W en el formulario (KeyUp)";
                textBox3.Text += "\r\nTecla W en el formulario (KeyUp)";
                break;
        }
    
    }
    
    
    // el orden de pulsación es:
    //  KeyDown, KeyPress y KeyUp
    
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        // e.KeyValue el código numérico
        textBox3.Text += "\r\ntextBox1_KeyDown, tecla: " + e.KeyCode;
    }
    
    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        textBox3.Text += "\r\ntextBox1_KeyPress, tecla: " + e.KeyChar;
    }
    
    private void textBox1_KeyUp(object sender, KeyEventArgs e)
    {
        textBox3.Text += "\r\ntextBox1_KeyUp, tecla: " + e.KeyValue;
    }
    
    

    Código de ejemplo para VB:

    Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
        Select Case e.KeyChar
            Case ChrW(Keys.W), ChrW(Keys.W + 32) ' mayúsculas y minúsculas
                label3.Text &= vbCrLf & "Tecla W en el formulario"
                textBox3.Text &= vbCrLf & "Tecla W en el formulario (KeyPress)"
            Case ChrW(Keys.S), ChrW(Keys.S + 32)
                label3.Text &= vbCrLf & "Tecla S en el formulario"
    
        End Select
    End Sub
    
    Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
        ' da igual mayúsculas que minúsculas
        Select Case e.KeyCode
            Case Keys.S
                label3.Text = "Tecla S en el formulario (KeyDown)"
            Case Keys.W
                label3.Text = "Tecla W en el formulario (KeyDown)"
                textBox3.Text &= vbCrLf & "Tecla W en el formulario (KeyDown)"
        End Select
    End Sub
    
    Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
        Select Case e.KeyCode
            Case Keys.S
                label3.Text = "Tecla S en el formulario (KeyUp)"
            Case Keys.W
                label3.Text = "Tecla W en el formulario (KeyUp)"
                textBox3.Text &= vbCrLf & "Tecla W en el formulario (KeyUp)"
        End Select
    End Sub
    
    
    ' el orden de pulsación es:
    ' KeyDown, KeyPress y KeyUp
    
    Private Sub textBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles textBox1.KeyDown
        ' e.KeyValue el código numérico
        textBox3.Text &= vbCrLf & "textBox1_KeyDown, tecla: " & e.KeyCode
    End Sub
    
    Private Sub textBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles textBox1.KeyPress
        textBox3.Text &= vbCrLf & "textBox1_KeyPress, tecla: " & e.KeyChar
    End Sub
    
    Private Sub textBox1_KeyUp(sender As Object, e As KeyEventArgs) Handles textBox1.KeyUp
        textBox3.Text &= vbCrLf & "textBox1_KeyUp, tecla: " & e.KeyValue
    End Sub
    

    Y esto es todo, espero que te sea de utilidad.

    Y si quieres ver más cosas de cómo detectar la tecla pulsada o cambiar el valor de esa pulsación, lee esto: Detectar la pulsación de teclas.

    Nos vemos.

    Guillermo

    El código del ejemplo

    Este es el proyecto del código mostrado.

    Lo he creado con Visual Studio 2013 Preview, pero el código es completamente compatible con cualquier versión de Visual Studio .NET, aunque es posible que los proyectos solo los puedas abrir con Visual Studio 2010 o posterior (no lo he comprobado).

    Lo que si es seguro es que si añades el formulario a un proyecto creado con cualquier versión de Visual Studio .NET que utilicen el .NET 2.0 o superior, si que te servirá.

    Nombre fichero: Detectar_tecla_en_formulario.zip

    Tamaño: 140 KB (143 434 bytes)

    Fecha: 21 septiembre 2013 14:15:32

    MD5: B80281EBF0C032FBF9487C5B251FD1BB

    …

  • 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

    …

  • 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

    …