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 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.
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
|
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
|