Procurando algo?

quarta-feira, 14 de dezembro de 2011

Filtrando entrada de dados no Windows Phone 7

Bom, comecei definitivamente a estudar o desenvolvimento de Windows Phone 7. Tive que comprar um novo Laptop pois o antigo já não aguentava o Visual Studio 2010 em toda sua glória e majestade :D Acabei comprando esse carinha aqui:


É um bom laptop e com 8GB em Dual Channel ficou melhor ainda. O teclado centralizado ajuda bastante na hora de digitar muitas linhas de código.

Bom, voltando ao Windows Phone 7, hoje aprendí uma coisa muito interessante sobre o teclado sobreposto do aparelho. Primeiro, você pode definir que teclas aparecerão na tela definindo a propriedade InputScope de um TextBox ou PasswordBox. Dessa forma, o teclado se ajusta ao contexto desejado para aquele campo e exibe somente teclas permitidas para aquele campo.

Os modos disponíveis estão na enumeração InputScopeNameValue e são 62 no total, embora só existam, hoje, 11 modos de teclados diferentes. Talvez os outros sirvam como placeholders para lançamentos futuros ou simplesmente para documentação adicional pra quem for ler seu código. Os modos Digit e Number, por exemplo, exibem as mesmas teclas, porém, se você escolher adequadamente, pode evitar ter que reescrever um trecho de código quando sair o Windows Phone "Rambo" ou "Mambo", sei lá.

Alguns são extremamente interessantes como o modo Chat que exibe abreviaturas para LOL, ROFL, Lolz e outros, bem como emoticons, bem úteis na hora de enviar SMS.  Também tem o modo Maps que carrega sugestões direto do Bing Maps conforme você digita o nome da cidade.

Modo Chat

Modo Number

Para escolher o InputScope desejado, basta adicionar tal informação direto no código XAML do controle. Assim:

<TextBox InputScope="PhoneNumber" />

Fácil, não?
Só que alguns telefones possuem teclado físico deslizante e isso não vai impedí-lo de digitar letras em um campo que só deve aceitar números. Então, você precisa impedir que isso aconteça via código. E é bem simples, veja:

void TextBox_KeyDown(object sender, KeyEventArgs e)
{
    switch(e.Key)
    {
        case Key.D0: case Key.D1: case Key.D2: case Key.D3: case Key.D4:
        case Key.D5: case Key.D6: case Key.D7: case Key.D8: case Key.D9:
            if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
            {
                // O Shift foi pressionado! Isso não é um bug. Acontece que o
                // usuário tentou digitar !@#$%¨&*() que ficam nas mesmas teclas
                // dos dígitos. Isso não é permitido, então engole essa tecla!
                e.Handled = true;
            }
            else
            {
                // Isso pode, então não faça nada. 
            }
            break;
        default:
            // Isso não pode, Segura aê!
            e.Handled = true;
            break;
    }
}

Pronto! Agora além de fornecer apenas as teclas relevantes ao contexto, você também restringiu a entrada incorreta.

segunda-feira, 27 de junho de 2011

Code Music 2

using System;
using System.Text;
using Mundo;
 
namespace Funk
{
 public class SouFoda : IFunk
 {
  // Dig-din, dig-din, di-din
  this.Foda = true;

  public SouFoda()
  {
   Console.WriteLine(Foda.toString());
  }

  if(NaCama || NaSala || NoQuarto || NoBeco || NoCarro)
   this.Esculachar(vc);

  this.Sinistro = true;

  seuMarido.Qualidade = this.Qualidade * -1

  this.Esculachar(seuAmigo);

  while(NaCama)
   this.Perigoso = true;

  // Avassalador
  this.Interessante = true;

  this.Esculachar(seuAmante);
  this.Esculachar(seuFicante);

  Console.WriteLine("Não se esqueça");

  this.Vagabundo = true;

  Mundo.Putaria();

  #region [ REFRÃO ]
  for (i = 0; i < 2; i++)
  {
   for (i = 0; i < 2; i++)
    this.Enlouquecer(vc);

   foreach(Mulher m in queProvaram)
   m.Esquecer = false;
  }
  #endregion
 }
}

Code Music

Você sabe que música é essa?

this.NoOsso = true;

Biscoito b = new Biscoito();
Ganso g = new Ganso();

for(i = 2; i <= 8; i++)
 Console.Write(i);

this.Molhar(b);

this.Cansado = !this.NoOsso;

this.Afogar(g);

quinta-feira, 19 de maio de 2011

Expressões regulares

Expressões regulares são bem úteis e muitos programadores .NET acabam ignorando-as por serem herança do mundo Unix.

Porém, quando se dá a elas a devida atenção, vantagens são descobertas e códigos que levariam n+1 linhas para fazer validação de entrada, acabam por se apresentarem em apenas uma linha. Veja o exemplo de um método que valida telefones:

static bool IsPhone(string s)
{
    return Regex.IsMatch(s, @"^\(?\d{3}\)?[\s\-]?\d{3}\-?\d{4}$");
}

Mas o que raios é esse monte de treco entre as aspas?

Eu explico:

^ Representa o início da string. Quando você usa este símbolo, significa que você está trabalhando a string desde seu início.
\(? Um parênteses opcional. Para validar parênteses, é necessário usar com escape \ e para tornar o símbolo opcional, usa-se ?
\d{3} Três dígitos numéricos. \d significa dígito  e o número entre chaves identifica a quantidade que se está buscando.
\)? Fechamento de parênteses opcional. Novamente um parênteses, dessa vez fechando mas também é opcional graças ao ?
[\s\-]? Ou um ou outro. Nesse caso, estamos buscando OU um espaço vazio por \s OU um hifem por \- . Devido a estarem entre colchetes, nunca serão encontrados ao mesmo tempo. E seja lá qual for que encontremos, é opcional de qualquer maneira.
\d{3} Três dígitos. Isso eu já expliquei :D
\-? Um hífem. Apenas um hífem. Mas é opcional, se não tiver, tudo bem.
\d{4} Adivinha?
$ Final da string. Este símbolo indica o final da string. Como usamos ^ no começo e $ no final, estamos testando a string inteira.

Zenit Polar e texto ao contrário

Dois métodos simples. Apenas por diversão.
/// 
/// Criptografa usando o algorítmo Zenit Polar
/// 
/// O texto de entrada/// Texto criptografado
private string ZenitPolar(string p)
{
    String s;
    s = p;

    s = s.Replace("z", "wx");
    s = s.Replace("p", "z");
    s = s.Replace("wx", "p");

    s = s.Replace("e", "wx");
    s = s.Replace("o", "e");
    s = s.Replace("wx", "o");

    s = s.Replace("n", "wx");
    s = s.Replace("l", "n");
    s = s.Replace("wx", "l");

    s = s.Replace("i", "wx");
    s = s.Replace("a", "i");
    s = s.Replace("wx", "a");

    s = s.Replace("t", "wx");
    s = s.Replace("r", "t");
    s = s.Replace("wx", "r");

    return s;
}

/// 
/// Inverte o texto
/// 
/// O texto de entrada/// O texto invertido
private string Reverse(string txt)
{
    StringBuilder sb = new StringBuilder();

    for (int i = txt.Length; i > 0; i--)
        sb.Append(txt[i-1]);

    return sb.ToString();
}