Ir al índice de .NET .NET Compact Framework
 

Usar VisibleDesktop para saber el espacio libre al mostrar/ocultar el InputPanel

 
Publicado el 21/Feb/2007
Actualizado el 21/Feb/2007
Autor: Guillermo 'guille' Som

En este artículo te explico cómo usar la propiedad VisibleDesktop de un InputPanel (o SIP) para saber el espacio libre al mostrar u ocultar ese panel de escritura en un PocketPC.
Como de costumbre con el código tanto para Visual Basic como para Visual C#.


Introducción:

No me voy a enrollar demasiado explicándote de que va esto del InputPanel (también conocido como SIP o Soft Input Panel), ya que si tienes una PocketPC sabrás que es el "teclado" que puede ocultarse o mostrarse en la parte inferior (al final si que te he dicho lo que es el SIP).

Ese teclado "virtual" tiene unas dimensiones (tamaño) cuando se muestra, por tanto, es posible que parte de lo que estemos usando en la "ventana" de la PocketPC se oculte cuando dicho teclado (también se puede mostrar como otra forma de entrada que no sea con forma de teclado) se muestre.

Hace unos años te expliqué cómo controlar por código que se oculte o se muestre el InputPanel, y en ese artículo te dije que te contaría cómo calcular el espacio disponible según esté o no visible ese panel, pero... (como suele ocurrirme algunas veces), pues no lo conté en su día, así que, aquí lo tienes.

 

Para ver cómo se controla ese espacio que se "pierde" cuando se muestra el InputPanel, he creado un ejemplo muy básico en el que hay unas cajas de texto, unos botones y unas etiquetas, una de ellas la uso para informar de ciertas cosas que ocurren, por ejemplo que haya algún error o el resultado de unas operaciones que haremos con dos números (es como una mini calculadora).

El InputPanel lo puedes ocultar o mostrar pulsando en el icono que hay para eso en las PocketPC, pero también lo puedes hacer por código (como te expliqué en el artículo que te comenté antes), en este ejemplo veremos cómo mostrarlo u ocultarlo según las cajas de texto reciban el foco o lo pierdan respectivamente.

Cuando se muestra u oculta el InputPanel, es decir, cuando la propiedad Enabled cambia de verdadero a falso, se produce el evento EnabledChanged, por tanto, será en ese evento donde haremos todo lo que tengamos que hacer, que como verás no es demasiado.

El control InputPanel (en realidad no es un control, sino un componente que gestiona ese "cacharrillo" de los PocketPC) tiene una propiedad llamada VisibleDesktop que cambia según se muestre u oculte el InputPanel.
Esa propiedad (que es de tipo Rectangle) tiene el espacio disponible de la ventana, de forma que si se muestra u oculta el InputPanel, la propiedad Height de esa propiedad tendrá el tamaño adecuado al espacio disponible, por tanto, usaremos esa propiedad del "rectángulo visible" para saber cuanto espacio podemos usar, en nuestro ejemplo, por la etiqueta que muestra la información, y a la que he llamado labelInfo (ocurrente, ¿verdad?).

Antes de ver el código, (tanto para Visual Basic como para C#), vamos a ver dos capturas de la aplicación en funcionamiento dentro del emulador que incluye Visual Studio 2005. En una de ellas (figura 1) se muestra el InputPanel, por tanto, la etiqueta se hace más pequeña. En la segunda captura (figura 2) el InputPanel está oculto, por tanto, la etiqueta es más grande.

 

Figura 1. El SIP se muestra
Figura 1. El SIP se muestra

 

Figura 2. El SIP está oculto
Figura 2. El SIP está oculto

 

En el evento GotFocus de las tres cajas de texto "habilitamos" el InputPanel, de forma que nos aseguramos de que se muestre.

' Al recibir el foco, mostrar el SIP
Private Sub txtNum1_GotFocus(ByVal sender As Object, _
            ByVal e As System.EventArgs) _
            Handles txtNum1.GotFocus, txtNum2.GotFocus, txtNum3.GotFocus
    Me.inputPanel1.Enabled = True
End Sub

 

// Al recibir el foco, mostrar el SIP
private void txtNum1_GotFocus(object sender, EventArgs e)
{
    this.inputPanel1.Enabled = true;
}

 

 

En el evento LostFocus de esos mismos controles deshabilitamos el InputPanel para que se oculte.

' Al perder el foco, ocultar el SIP
Private Sub txtNum1_LostFocus(ByVal sender As Object, _
            ByVal e As System.EventArgs) _
            Handles txtNum1.LostFocus, txtNum2.LostFocus, txtNum3.LostFocus
    Me.inputPanel1.Enabled = False
End Sub

 

// Al perder el foco, ocultar el SIP
private void txtNum1_LostFocus(object sender, EventArgs e)
{
    this.inputPanel1.Enabled = false;
}

 

 

Cuando cambia el estado "habilitado" del InputPanel se produce el evento EnabledChanged, por tanto, en ese evento es donde tendremos que hacer todo lo que tengamos que hacer para ajustar los controles.
Ese evento también se produce cuando se pulsa en el icono, por tanto, también nos servirá si en vez de cambiar la visibilidad del InputPanel por código se hace porque el usuario esté aburrido pulsando en ese icono... (algunas veces ocurre que el usuario se aburre... de verdad).

' Este evento se produce cuando cambia el estado del SIP
' Enabled = True (visible), Enabled = False (oculto)
' ya sea mediante código o pulsando en el icono del PocketPC
'
' Si no hacemos nada especial la etiqueta del final se ocultará por el SIP.
' Podemos ajustar el tamaño de esa etiqueta al tamaño restante.
Private Sub inputPanel1_EnabledChanged(ByVal sender As Object, _
            ByVal e As System.EventArgs) _
            Handles inputPanel1.EnabledChanged
    ' El tamaño visible de la ventana
    Dim vRect As Rectangle = inputPanel1.VisibleDesktop

    ' Si se muestra el SIP, reducir el alto de la etiqueta
    ' si se oculta, hacer que ocupe todo el alto restante.
    ' En ambos casos se deja un margen en la parte inferior.
    If inputPanel1.Enabled Then
        ' El SIP es visible, hacer más pequeña la etiqueta
        labelInfo.Height = vRect.Height - labelInfo.Top - 8
    Else
        ' El SIP no es visible, hacer más grande la etiqueta
        labelInfo.Height = vRect.Height - labelInfo.Top - 32
    End If

End Sub

 

// Este evento se produce cuando cambia el estado del SIP
// Enabled = True (visible), Enabled = False (oculto)
// ya sea mediante código o pulsando en el icono del PocketPC
//
// Si no hacemos nada especial la etiqueta del final se ocultará porel SIP.
// Podemos ajustar el tamaño de esa etiqueta al tamaño restante.
private void inputPanel1_EnabledChanged(object sender, EventArgs e)
{
    // El tamño visible de la ventana
    Rectangle vRect = inputPanel1.VisibleDesktop;

    // Si se muestra el SIP, reducir el alto de la etiqueta
    // si se oculta, hacer que ocupe todo el alto restante.
    // En ambos casos se deja un margen en la parte inferior.
    if (inputPanel1.Enabled)
    {
        // El SIP es visible, hacer más pequeña la etiqueta
        labelInfo.Height = vRect.Height - labelInfo.Top - 8;
    }
    else
    {
        // El SIP no es visible, hacer más grande la etiqueta
        labelInfo.Height = vRect.Height - labelInfo.Top - 32;
    }
}

 

Como puedes ver en el código anterior, el alto de la etiqueta informativa (labelInfo) se ajusta según el valor de la altura del área visible, pero teniendo en cuenta la posición Top de esa etiqueta, además de unos valores "manuales" para que no se agrande más de la cuenta... cálculos que seguramente tendrás que hacer tú para que la cosa quede como quieres que quede...

 

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

Nos vemos.
Guillermo

Aquí tienes el código completo del formulario, tanto para Visual Basic como para Visual C#.
El proyecto de ejemplo está creado con la versión 2005, pero también es compatible con la versión 2003.

Más abajo tienes el ZIP con los proyectos, tanto para Visual Basic como para C#, uno de ellos (solo para VB) está creado usando la versión 1.0 de Compact .NET Framework, los otros dos, con la versión 2.0.
En los tres casos, he usado Visual Studio 2005 y en teoría solo es para PocketPC 2003 o superior.

 


Código para Visual Basic.NET (VB.NET)El código para Visual Basic .NET

'------------------------------------------------------------------------------
' Prueba del InputPanel (SIP) con Visual Basic 2005                 (21/Feb/07)
'
' ©Guillermo 'guille' Som, 2007
'------------------------------------------------------------------------------
Option Strict On

Imports Microsoft.VisualBasic
Imports vb = Microsoft.VisualBasic
Imports System
Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) _
                Handles MyBase.Load
        ' El mensaje a mostrar en la etiqueta de avisos
        labelInfo.Text = "Escribe los dos números con los que quieres operar " & _
                         "y pulsa en el botón correspondiente a la operación a realizar."
        ' Guardar el mensaje genérico
        labelInfo.Tag = labelInfo.Text
    End Sub

    ' Los botones para realizar las operaciones
    Private Sub btnSuma_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) _
                Handles btnSuma.Click
        Me.txtNum3.Text = resultado(txtNum1.Text, txtNum2.Text, "+")
    End Sub

    Private Sub btnResta_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) _
                Handles btnResta.Click
        Me.txtNum3.Text = resultado(txtNum1.Text, txtNum2.Text, "-")
    End Sub

    Private Sub btnMultiplica_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) _
                Handles btnMultiplica.Click
        Me.txtNum3.Text = resultado(txtNum1.Text, txtNum2.Text, "*")
    End Sub

    Private Sub btnDivide_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) _
                Handles btnDivide.Click
        Me.txtNum3.Text = resultado(txtNum1.Text, txtNum2.Text, "/")
    End Sub

    ' Métodos para calcular los valores de los números con los que operar
    Private Function resultado(ByVal num1 As String, _
                               ByVal num2 As String, _
                               ByVal op As String) As String
        Dim bMal As Integer = 0
        If vb.IsNumeric(num1) = False Then
            bMal = 1
        End If
        If vb.IsNumeric(num2) = False Then
            bMal = 2
        End If
        If bMal <> 0 Then
            labelInfo.Text = "Debes indicar valores numéricos correctos."
            If bMal = 1 Then
                Me.txtNum1.Focus()
            Else
                Me.txtNum2.Focus()
            End If
            Return ""
        End If
        Dim n1 As Double = CDbl(num1)
        Dim n2 As Double = CDbl(num2)
        Dim n3 As Double
        Select Case op
            Case "+"
                n3 = n1 + n2
            Case "-"
                n3 = n1 - n2
            Case "*"
                n3 = n1 * n2
            Case "/"
                n3 = n1 / n2
        End Select
        labelInfo.Text = String.Format(" La operación {0} {1} {2} = {3}", n1, op, n2, n3)
        Return n3.ToString()
    End Function

    ' Los eventos en las cajas de texto para mostrar ocultar el SIP (InputPanel)
    '

    ' Al recibir el foco, mostrar el SIP
    Private Sub txtNum1_GotFocus(ByVal sender As Object, _
                ByVal e As System.EventArgs) _
                Handles txtNum1.GotFocus, txtNum2.GotFocus, txtNum3.GotFocus
        Me.inputPanel1.Enabled = True
    End Sub

    ' Al perder el foco, ocultar el SIP
    Private Sub txtNum1_LostFocus(ByVal sender As Object, _
                ByVal e As System.EventArgs) _
                Handles txtNum1.LostFocus, txtNum2.LostFocus, txtNum3.LostFocus
        Me.inputPanel1.Enabled = False
    End Sub

    ' Este evento se produce cuando cambia el estado del SIP
    ' Enabled = True (visible), Enabled = False (oculto)
    ' ya sea mediante código o pulsando en el icono del PocketPC
    '
    ' Si no hacemos nada especial la etiqueta del final se ocultará por el SIP.
    ' Podemos ajustar el tamaño de esa etiqueta al tamaño restante.
    Private Sub inputPanel1_EnabledChanged(ByVal sender As Object, _
                ByVal e As System.EventArgs) _
                Handles inputPanel1.EnabledChanged
        ' El tamaño visible de la ventana
        Dim vRect As Rectangle = inputPanel1.VisibleDesktop

        ' Si se muestra el SIP, reducir el alto de la etiqueta
        ' si se oculta, hacer que ocupe todo el alto restante.
        ' En ambos casos se deja un margen en la parte inferior.
        If inputPanel1.Enabled Then
            ' El SIP es visible, hacer más pequeña la etiqueta
            labelInfo.Height = vRect.Height - labelInfo.Top - 8
        Else
            ' El SIP no es visible, hacer más grande la etiqueta
            labelInfo.Height = vRect.Height - labelInfo.Top - 32
        End If

        'labelInfo.Text = String.Format( _
        '            "vRect.Height = {0}, lInfo.Top = {1}, lInfo.Height = {2}", _
        '            vRect.Height, labelInfo.Top, labelInfo.Height)
    End Sub

    Private Sub mnuCerrar_Click(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) _
                Handles mnuCerrar.Click
        Me.Close()
    End Sub
End Class

 


Código para C Sharp (C#)El código para C#

//-----------------------------------------------------------------------------
// Prueba del InputPanel (SIP) con Visual Basic 2005                (21/Feb/07)
//
// ©Guillermo 'guille' Som, 2007
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace usarSIP_cs
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // El mensaje a mostrar en la etiqueta de avisos
            labelInfo.Text = "Escribe los dos números con los que quieres operar " + 
                             "y pulsa en el botón correspondiente a la operación a realizar.";
            // Guardar el mensaje genérico
            labelInfo.Tag = labelInfo.Text;
        }

        // Los botones para realizar las operaciones
        private void btnSuma_Click(object sender, EventArgs e)
        {
            this.txtNum3.Text = resultado(txtNum1.Text, txtNum2.Text, "+");
        }

        private void btnResta_Click(object sender, EventArgs e)
        {
            this.txtNum3.Text = resultado(txtNum1.Text, txtNum2.Text, "-");
        }

        private void btnMultiplica_Click(object sender, EventArgs e)
        {
            this.txtNum3.Text = resultado(txtNum1.Text, txtNum2.Text, "*");
        }

        private void btnDivide_Click(object sender, EventArgs e)
        {
            this.txtNum3.Text = resultado(txtNum1.Text, txtNum2.Text, "/");
        }

        // Métodos para calcular los valores de los números con los que operar
        private string resultado(string num1, string num2, string op)
        {
            int bMal = 0;
            double n1 = 0;
            double n2 = 0;
            double n3 = 0;

            try
            {
                n1 = Convert.ToDouble(num1);
            }
            catch
            {
                bMal = 1;
            }
            try
            {
                n2 = Convert.ToDouble(num2);
            }
            catch
            {
                bMal = 2;
            }
            if (bMal != 0)
            {
                labelInfo.Text = "Debes indicar valores numéricos correctos.";
                if (bMal == 1)
                {
                    this.txtNum1.Focus();
                }
                else
                {
                    this.txtNum2.Focus();
                }
                return "";
            }

            switch (op)
            {
                case "+":
                    n3 = n1 + n2;
                    break;
                case "-":
                    n3 = n1 - n2;
                    break;
                case "*":
                    n3 = n1 * n2;
                    break;
                case "/":
                    n3 = n1 / n2;
                    break;
            }
            labelInfo.Text = String.Format(" La operación {0} {1} {2} = {3}", n1, op, n2, n3);
            return n3.ToString();
        }

        // Los eventos en las cajas de texto para mostrar ocultar el SIP (InputPanel)
        //
        // Al recibir el foco, mostrar el SIP
        private void txtNum1_GotFocus(object sender, EventArgs e)
        {
            this.inputPanel1.Enabled = true;
        }

        // Al perder el foco, ocultar el SIP
        private void txtNum1_LostFocus(object sender, EventArgs e)
        {
            this.inputPanel1.Enabled = false;
        }

        // Este evento se produce cuando cambia el estado del SIP
        // Enabled = True (visible), Enabled = False (oculto)
        // ya sea mediante código o pulsando en el icono del PocketPC
        //
        // Si no hacemos nada especial la etiqueta del final se ocultará por el SIP.
        // Podemos ajustar el tamaño de esa etiqueta al tamaño restante.
        private void inputPanel1_EnabledChanged(object sender, EventArgs e)
        {
            // El tamaño visible de la ventana
            Rectangle vRect = inputPanel1.VisibleDesktop;

            // Si se muestra el SIP, reducir el alto de la etiqueta
            // si se oculta, hacer que ocupe todo el alto restante.
            // En ambos casos se deja un margen en la parte inferior.
            if (inputPanel1.Enabled)
            {
                // El SIP es visible, hacer más pequeña la etiqueta
                labelInfo.Height = vRect.Height - labelInfo.Top - 8;
            }
            else
            {
                // El SIP no es visible, hacer más grande la etiqueta
                labelInfo.Height = vRect.Height - labelInfo.Top - 32;
            }

            //labelInfo.Text = String.Format( 
            //            "vRect.Height = {0}, lInfo.Top = {1}, lInfo.Height = {2}", 
            //            vRect.Height, labelInfo.Top, labelInfo.Height);
        }

        private void mnuCerrar_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }

 


Espacios de nombres usados en el código de este artículo:

System.Windows.Forms
 


Código de ejemplo (comprimido):

 

Fichero con el código de ejemplo: usarSIP.zip - 112.0 KB

Contiene tres proyectos, dos de Visual Basic y uno de C#.
Dos de esos proyectos (uno de VB y otro de C#) están creados usando la versión 2.0 del Compact Framework.
El otro de Visual Basic utiliza la versión 1.0 del .NET Compact Framework.
Los tres proyectos están creados con Visual Studio 2005 y son para PocketPC 2003 o superior.

(MD5 checksum: 6D9140098FD1FCFB74B2FF3C9EF672C0)

 


Ir al índice principal de el Guille

Valid XHTML 1.0 Transitional ¡CSS Válido!