Arquivo

Archive for the ‘C#’ Category

Código único com NanoID.net

Nas suas aplicações, quantas vezes você já precisou de um código único? Seja para identificar um cadastro, um produto no pedido, etc?

O GUID é confiável, mas tem um tamanho exagerado, não? Podemos concordar que ele é ininteligível e difícil de decorar?

Pois bem, encontrei uma alternativa que gostaria de compartilhar: HASH-ID.

Uma biblioteca openSource que tem implementações em diversas linguagens e plataformas: JavaScript, Ruby, Python, Java, Scala, PHP, Perl, Perl 6, Swift, Clojure, Objective-C, C, C++11, D, F#, Go, Erlang, Lua, Haskell, OCaml, Elixir, Rust, Smalltalk, ColdFusion, Kotlin, Nim, VBA, Haxe, Crystal, Elm, ActionScript, Bash, R, TSQL, PostgreSQL, PLpgSQL, Dart, Io and for .NET

É muito fácil de usar. Veja um exemplo de código em CSharp:

public string GerarCodigoDaVenda(){
  return Nanoid.Nanoid.Generate( 
     alphabet: "1234567890abcdefghijklmnopqrstuwvxyz", 
     size: 10
   );                
}

No trecho de código acima, eu delimitei a variedade de caracteres que o NanoID vai utilizar, além de especificar o tamanho em 10 caracteres.

Na biblioteca você pode gerar inúmeras variações:

Normal

Na modalidade padrão, o método usa símbolos amigáveis com URLS (A-Za-z0-9_~), e retorna um ID com 21 caracteres (chances de colisão similares ao formato UUID v4).

var id = Nanoid.Generate() //=> "Uakgb_J5m9g~0JDMbcJqLJ"

Símbolos -,.() não são codificados em URL´s.

Se você quiser reduzir o tamanho do ID, passe o tamanho como argumento:

var id = Nanoid.Generate(size:10) //=> "IRFa~VaY2b"

Customizando o alfabeto:

var id = Nanoid.Generate('1234567890abcdef', 10) //=> "4f90d13a42"

A variação de caracteres deve conter 256 símbolos ou menos. De outra forma não será seguro.

Referências:

https://hashids.org/

Implementação em javascript: https://github.com/ai/nanoid

Implementação p/ .net: https://github.com/codeyu/nanoid-net

Conversão de número e porcentagem para extenso em C#

12 - 13 1 comentário

A partir da necessidade de converter valores em Reais R$ para extenso, encontrei na internet um código que fazia essa conversão.

Artigo original: http://ivanmeirelles.wordpress.com/2012/10/27/escrever-valores-por-extenso-em-c/

Posteriormente, precisei fazer uma conversão de porcentagem %% para extenso, e fiz uma pequena modificação no código para suportar essa conversão.

O Snippet de código está no link abaixo:

A classe suporta a conversão de decimal, valor monetário e porcentagem para extenso, em PT-BR.

public static class Extenso
    {
        public enum TipoValorExtenso
        {
            Monetario,
            Porcentagem,
            Decimal
        }

        public static string toExtenso(double Valor, TipoValorExtenso tipoValorExtenso)
        {
            decimal valorEscrever = new decimal(Valor);

            return toExtenso(valorEscrever, tipoValorExtenso);
        }

        // O método toExtenso recebe um valor do tipo decimal
        public static string toExtenso(decimal valor, TipoValorExtenso tipoValorExtenso)
        {
            if (valor <= 0 | valor >= 1000000000000000)
                throw new ArgumentOutOfRangeException("Valor não suportado pelo sistema. Valor: " + valor);

            string strValor = String.Empty;
            strValor = valor.ToString("000000000000000.00#");
            //strValor = valor.ToString("{0:0.00#}");
            string valor_por_extenso = string.Empty;
            int qtdCasasDecimais =
                strValor.Substring(strValor.IndexOf(',') + 1, strValor.Length - (strValor.IndexOf(',') + 1)).Length;
            bool existemValoresAposDecimal = Convert.ToInt32(strValor.Substring(16, qtdCasasDecimais)) > 0;

            for (int i = 0; i <= 15; i += 3)
            {
                var parte = strValor.Substring(i, 3);
                // se parte contém vírgula, pega a substring com base na quantidade de casas decimais.
                if (parte.Contains(','))
                {
                    parte = strValor.Substring(i+1, qtdCasasDecimais);
                }
                valor_por_extenso += escreva_parte(Convert.ToDecimal(parte));
                if (i == 0 & valor_por_extenso != string.Empty)
                {
                    if (Convert.ToInt32(strValor.Substring(0, 3)) == 1)
                        valor_por_extenso += " TRILHÃO" +
                                             ((Convert.ToDecimal(strValor.Substring(3, 12)) > 0)
                                                  ? " E "
                                                  : string.Empty);
                    else if (Convert.ToInt32(strValor.Substring(0, 3)) > 1)
                        valor_por_extenso += " TRILHÕES" +
                                             ((Convert.ToDecimal(strValor.Substring(3, 12)) > 0)
                                                  ? " E "
                                                  : string.Empty);
                }
                else if (i == 3 & valor_por_extenso != string.Empty)
                {
                    if (Convert.ToInt32(strValor.Substring(3, 3)) == 1)
                        valor_por_extenso += " BILHÃO" +
                                             ((Convert.ToDecimal(strValor.Substring(6, 9)) > 0)
                                                  ? " E "
                                                  : string.Empty);
                    else if (Convert.ToInt32(strValor.Substring(3, 3)) > 1)
                        valor_por_extenso += " BILHÕES" +
                                             ((Convert.ToDecimal(strValor.Substring(6, 9)) > 0)
                                                  ? " E "
                                                  : string.Empty);
                }
                else if (i == 6 & valor_por_extenso != string.Empty)
                {
                    if (Convert.ToInt32(strValor.Substring(6, 3)) == 1)
                        valor_por_extenso += " MILHÃO" +
                                             ((Convert.ToDecimal(strValor.Substring(9, 6)) > 0)
                                                  ? " E "
                                                  : string.Empty);
                    else if (Convert.ToInt32(strValor.Substring(6, 3)) > 1)
                        valor_por_extenso += " MILHÕES" +
                                             ((Convert.ToDecimal(strValor.Substring(9, 6)) > 0)
                                                  ? " E "
                                                  : string.Empty);
                }
                else if (i == 9 & valor_por_extenso != string.Empty)
                    if (Convert.ToInt32(strValor.Substring(9, 3)) > 0)
                        valor_por_extenso += " MIL" +
                                             ((Convert.ToDecimal(strValor.Substring(12, 3)) > 0)
                                                  ? " E "
                                                  : string.Empty);

                if (i == 12)
                {
                    if (valor_por_extenso.Length > 8)
                        if (valor_por_extenso.Substring(valor_por_extenso.Length - 6, 6) == "BILHÃO" |
                            valor_por_extenso.Substring(valor_por_extenso.Length - 6, 6) == "MILHÃO")
                            valor_por_extenso += " DE";
                        else if (valor_por_extenso.Substring(valor_por_extenso.Length - 7, 7) == "BILHÕES" |
                                 valor_por_extenso.Substring(valor_por_extenso.Length - 7, 7) == "MILHÕES" |
                                 valor_por_extenso.Substring(valor_por_extenso.Length - 8, 7) == "TRILHÕES")
                            valor_por_extenso += " DE";
                        else if (valor_por_extenso.Substring(valor_por_extenso.Length - 8, 8) == "TRILHÕES")
                            valor_por_extenso += " DE";

                    if (Convert.ToInt64(strValor.Substring(0, 15)) == 1)
                    {
                        switch (tipoValorExtenso)
                        {
                            case TipoValorExtenso.Monetario:
                                valor_por_extenso += " REAL";
                                break;
                            case TipoValorExtenso.Porcentagem:
                                if (existemValoresAposDecimal == false)
                                    valor_por_extenso += " PORCENTO";
                                break;
                            case TipoValorExtenso.Decimal:
                                break;
                            default:
                                throw new ArgumentOutOfRangeException("tipoValorExtenso");
                        }
                    }

                    else if (Convert.ToInt64(strValor.Substring(0, 15)) > 1)
                    {
                        switch (tipoValorExtenso)
                        {
                            case TipoValorExtenso.Monetario:
                                valor_por_extenso += " REAIS";
                                break;
                            case TipoValorExtenso.Porcentagem:
                                if (existemValoresAposDecimal == false)
                                    valor_por_extenso += " PORCENTO";
                                break;
                            case TipoValorExtenso.Decimal:
                                break;
                            default:
                                throw new ArgumentOutOfRangeException("tipoValorExtenso");
                        }
                    }

                    if (Convert.ToInt32(strValor.Substring(16, 2)) > 0 && valor_por_extenso != string.Empty)
                    {
                        switch (tipoValorExtenso)
                        {
                            case TipoValorExtenso.Monetario:
                                valor_por_extenso += " E ";
                                break;
                            case TipoValorExtenso.Porcentagem:
                                valor_por_extenso += " VÍRGULA ";
                                break;
                            case TipoValorExtenso.Decimal:
                                break;
                            default:
                                throw new ArgumentOutOfRangeException("tipoValorExtenso");
                        }
                    }
                }

                if (i == 15)
                    if (Convert.ToInt32(strValor.Substring(16, qtdCasasDecimais)) == 1)
                    {
                        switch (tipoValorExtenso)
                        {
                            case TipoValorExtenso.Monetario:
                                valor_por_extenso += " CENTAVO";
                                break;
                            case TipoValorExtenso.Porcentagem:
                                valor_por_extenso += " CENTAVO";
                                break;
                            case TipoValorExtenso.Decimal:
                                break;
                            default:
                                throw new ArgumentOutOfRangeException("tipoValorExtenso");
                        }
                    }

                    else if (Convert.ToInt32(strValor.Substring(16, qtdCasasDecimais)) > 1)
                    {
                        switch (tipoValorExtenso)
                        {
                            case TipoValorExtenso.Monetario:
                                valor_por_extenso += " CENTAVOS";
                                break;
                            case TipoValorExtenso.Porcentagem:
                                valor_por_extenso += " PORCENTO";
                                break;
                            case TipoValorExtenso.Decimal:
                                break;
                            default:
                                throw new ArgumentOutOfRangeException("tipoValorExtenso");
                        }
                    }
            }
            return valor_por_extenso;
        }

        private static string escreva_parte(decimal valor)
        {
            if (valor <= 0)
                return string.Empty;
            else
            {
                string montagem = string.Empty;
                if (valor > 0 & valor < 1)
                {
                    valor *= 100;
                }
                string strValor = valor.ToString("000");
                int a = Convert.ToInt32(strValor.Substring(0, 1));
                int b = Convert.ToInt32(strValor.Substring(1, 1));
                int c = Convert.ToInt32(strValor.Substring(2, 1));

                if (a == 1) montagem += (b + c == 0) ? "CEM" : "CENTO";
                else if (a == 2) montagem += "DUZENTOS";
                else if (a == 3) montagem += "TREZENTOS";
                else if (a == 4) montagem += "QUATROCENTOS";
                else if (a == 5) montagem += "QUINHENTOS";
                else if (a == 6) montagem += "SEISCENTOS";
                else if (a == 7) montagem += "SETECENTOS";
                else if (a == 8) montagem += "OITOCENTOS";
                else if (a == 9) montagem += "NOVECENTOS";

                if (b == 1)
                {
                    if (c == 0) montagem += ((a > 0) ? " E " : string.Empty) + "DEZ";
                    else if (c == 1) montagem += ((a > 0) ? " E " : string.Empty) + "ONZE";
                    else if (c == 2) montagem += ((a > 0) ? " E " : string.Empty) + "DOZE";
                    else if (c == 3) montagem += ((a > 0) ? " E " : string.Empty) + "TREZE";
                    else if (c == 4) montagem += ((a > 0) ? " E " : string.Empty) + "QUATORZE";
                    else if (c == 5) montagem += ((a > 0) ? " E " : string.Empty) + "QUINZE";
                    else if (c == 6) montagem += ((a > 0) ? " E " : string.Empty) + "DEZESSEIS";
                    else if (c == 7) montagem += ((a > 0) ? " E " : string.Empty) + "DEZESSETE";
                    else if (c == 8) montagem += ((a > 0) ? " E " : string.Empty) + "DEZOITO";
                    else if (c == 9) montagem += ((a > 0) ? " E " : string.Empty) + "DEZENOVE";
                }
                else if (b == 2) montagem += ((a > 0) ? " E " : string.Empty) + "VINTE";
                else if (b == 3) montagem += ((a > 0) ? " E " : string.Empty) + "TRINTA";
                else if (b == 4) montagem += ((a > 0) ? " E " : string.Empty) + "QUARENTA";
                else if (b == 5) montagem += ((a > 0) ? " E " : string.Empty) + "CINQUENTA";
                else if (b == 6) montagem += ((a > 0) ? " E " : string.Empty) + "SESSENTA";
                else if (b == 7) montagem += ((a > 0) ? " E " : string.Empty) + "SETENTA";
                else if (b == 8) montagem += ((a > 0) ? " E " : string.Empty) + "OITENTA";
                else if (b == 9) montagem += ((a > 0) ? " E " : string.Empty) + "NOVENTA";

                if (strValor.Substring(1, 1) != "1" & c != 0 & montagem != string.Empty) montagem += " E ";

                if (strValor.Substring(1, 1) != "1")
                    if (c == 1) montagem += "UM";
                    else if (c == 2) montagem += "DOIS";
                    else if (c == 3) montagem += "TRÊS";
                    else if (c == 4) montagem += "QUATRO";
                    else if (c == 5) montagem += "CINCO";
                    else if (c == 6) montagem += "SEIS";
                    else if (c == 7) montagem += "SETE";
                    else if (c == 8) montagem += "OITO";
                    else if (c == 9) montagem += "NOVE";

                return montagem;
            }
        }
    }

Evitando Bind Injection com ASP.NET MVC

O título do post é sensacionalista, mas o conteúdo é sério.
O recurso de model binding nativo do ASP.NET MVC, oferece um sério risco, dependendo da forma que o desenvolvedor utilize o binding automático.

Imaginemos o seguinte senário:

Uma action que grava alterações no nome e e-mail de um usuário do sistema.
Há diversas formas de capturar no servidor os dados enviados pelo cliente.

Exemplo 1: Declarando na assinatura do método os parâmetros correspondentes aos campos postados no form:

public ActionResult Gravar(string Nome, string Email)
{
   // código de persistência
}

Exemplo 2: Obtendo os dados pelo objeto Request que contém os dados postados:

public ActionResult Gravar()
{
   string nome = Request["Nome"];
   string email = Request["Email"];
}

Exemplo 3: Setando o tipo do parâmetro para a classe que contém esses membros.

[HttpPost]
public ActionResult Gravar(User usuarioPostado)
{
   // código de persistência
}

Classe de domínio:

public class User
{
  public int Id { get; set; }
  public string Nome { get; set; }
  public string Email { get; set; }
  public bool IsAdmin { get; set; }
}

imagine que você criou uma view fortemente tipada, usando o gerador automático do Visual Studio, e sua view contém um campo que permite alterar a propriedade IsAdmin.

</pre>
<div class="editor-label">@Html.LabelFor(model => model.IsAdmin)</div>
<div class="editor-field">@Html.EditorFor(model => model.IsAdmin)
 @Html.ValidationMessageFor(model => model.IsAdmin)</div>
<pre>

Certamente você vai remover esse campo, ou marcá-lo como read only e deixá-lo lá na view.

Vulnerabilidade:
Alguém mal-intencionado pode postar essa informação livremente via GET, ou com um pouquinho mais de trabalho via POST, basta saber que existe esse campo no BD, e que o campo tem o nome de “isAdmin”, setar IS ADMIN = TRUE, e OBTER PERMISSÃO DE ADMINISTRADOR no seu sistema quando os dados forem persistidos.

Possíveis defesas:

Defesa 1: Utilizar o atributo Bind na classe de domínio.

[Bind(Exclude = "IsAdmin")] // É possível usar a propriedade Include, que informa quais membros são permitidos, ao invés de quais serão excluídos.
public class User
{
  public int Id { get; set; }
  public string Nome { get; set; }
  public string Email { get; set; }
  public bool IsAdmin { get; set; }
}

Defesa 2: Utilizar o atributo Bind no método de gravação.

[HttpPost]
public ActionResult Gravar([Bind(Exclude = "IsAdmin")] User usuarioPostado)
{
   // código de persistência
}

Defesa 3: Utilizar uma ViewModel para trocar dados entre a view e o seu controller:

public class UserInputViewModel
{
  public int Id { get; set; }
  public string Nome { get; set; }
  public string Email { get; set; }
}

[HttpPost]
public ActionResult Gravar(UserInputViewModel usuarioPostado)
{
   // converte a classe UserInputViewModel => em User
   // Uma dica é usar a biblioteca AutoMapper: https://github.com/AutoMapper/AutoMapper
   // efetua a persistência.
}

Existem mais defesas possíveis, e uma dica interessante que aprendi é:
“Trate qualquer HTTP request como malicioso até que se prove o contrário.”.

Fontes:
IronShay | Mass Assignment Vulnerability in ASP.NET MVC

6 Ways To Avoid Mass Assignment in ASP.NET MVC

Conversão segura de strings com TryParse em C#

10 - 12 2 comentários

Para fazer conversões seguras de strings em algum outro datatype podemos utilizar o método TryParse.

Sintaxe

boolean tipodedado.TryParse(string_tentar_converter, out variavel_retorno)

No método TryParse, você informa uma string qualquer que será convertida, e uma variável de retorno com o argumento “out”. Se a conversão for bem sucedida é retornado true, caso contrário, false.

Conversão insegura:

Abaixo um trecho de código que vai gerar uma exceção:

object s = "5b"; // não é possível converter 5b para inteiro.
int a = (int) s; // Dá erro e gera uma exceção

 

object s = "3e"; // não é possível converter 5e para inteiro
int a = Convert.ToInt32(s); // Dá erro e gera uma exceção

Conversão segura:

int numero;
bool resultado = int.TryParse("5b", out numero);

Nesse trecho de código a variável “numero” tera o valor (0) zero, pois não é possível converter 5b para inteiro — o detalhe é que, não será disparada uma exceção.

Outras classes com métodos TryParse:

  • Char.TryParse
  • Guid.TryParse
  • DateTime.TryParse
  • Enum.TryParse
  • Decimal.TryParse
  • Double.TryParse
  • IPAddress.TryParse

Fica a dica.

Categorias:C#, Dicas / Tips Tags:

Imagens no Oracle com NHibernate, Asp.net Mvc e C#

Cenário:
Um site de um concurso cultural, ao cadastrar uma promoção o usuário envia uma imagem que vai ser exibida com a promoção. Essa imagem é gravada no oracle com nhibernate, e é retornada sempre que a promoção é exibida ao usuário.

Exemplo resumido da classe Promoção:

public class Promocao
{
public virtual string Nome { get; set; }

public virtual string Desafio { get; set; }

public virtual string Regulamento { get; set; }

public virtual byte[] ImagemTopo { get; set; }
// Criamos a propriedade como um array de bytes -> byte[] que será persistido como binário.
}

Resumo da classe mapeada com Fluent NHibernate:

    public class PromocaoMap : ClassMap<Promocao>
    {
        public PromocaoMap()
        {
            .... omitido...            
            // Mapeei um campo para o regulamento da promoção e um campo para a imagem do topo
            Map(x => x.Regulamento).Length(1048576); // length de 1048576 bytes aproximadamente 1 mb -> será criado como NCLOB no oracle.
            Map(x => x.ImagemTopo).Length(5224880); // length 5224880 bytes aproximadamente 5 mb -> será criado como BLOB no oracle.
        }
    }

Gravando a imagem no banco

Código da Action que Recebe o Post do Form de Cadastro:

[HttpPost]
public ActionResult SavePromocao(Promocao promocaoGravar, HttpPostedFileBase ImagemTopoEnviar)
        {
            if (!ModelState.IsValid)
                return View("CadPromocao", promocaoGravar);

            using (var sessao = MvcApplication.ObterSessaoNh())
            {
                using (var transacao = sessao.BeginTransaction())
                {
                    try
                    {
                        var crud = new Dal.PromocaoDao(sessao);
                        if (promocaoGravar.Id <= 0)
                        {
                            crud.Incluir(promocaoGravar);
                        }
                        else
                        {
                            var objetoPersistido = crud.RetornaEntidade(promocaoGravar.Id);
                            objetoPersistido.Nome = promocaoGravar.Nome;

                            if (ImagemTopoEnviar != null)
                            {
                                // Converte stream do arquivo enviado para array de bytes[]
                                var memoryStream = new MemoryStream();
                                ImagemTopoEnviar.InputStream.CopyTo(memoryStream);

                                objetoPersistido.ImagemTopo = memoryStream.ToArray();
                            }

                            crud.Alterar(objetoPersistido);
                        }

                        transacao.Commit();
                    }
                    catch (Exception)
                    {
                        transacao.Rollback();
                    }
                }
            }

            return RedirectToAction("ListPromocoes");
        }

Dessa forma a imagem é persistida corretamente no Oracle.

Exibindo a imagem na view

Criar uma Action que busca a imagem no banco de dados e retorna via response

[HttpGet]
public ActionResult GetImagemPromocao(long idPromocao)
{
   byte[] imagemArray = null;

   using (var sessao = MvcApplication.ObterSessaoNh())
   {
	var crud = new Dal.PromocaoDao(sessao);
	imagemArray = crud.ObterImagem(idPromocao);
	if (imagemArray == null)
        {
		return null;
	}
	else
	{
		return new FileContentResult(imagemArray, "image/jpeg");
	} 
   }
} 

Código da View

// Minha View é TIPADA
<img src="@Url.Content("~/Admin/GetImagemPromocao?idPromocao = " + Model.Id)"/>

// O Helper Url.Content converte um Path Relativo para um Path Absoluto.

E assim a imagem é renderizada com sucesso na view.


Observações:

  1. Deve funcionar corretamente em outros SGBDS como MySql, PostgreSql e etc.
  2. Vale lembrar que o objeto byte[] armazena não somente imagems, mais qualquer outro tipo de arquivo, pois tudo é binário ok.
  3. Não inclui o tratamento de erros no exemplo.

Dúvidas deixe nos comentários que respondo.

Espero ter ajudado em seu projeto.


Referências:
Documentação do NHibernate – Tipos de Dados
Dica para converter Stream
no StackOverflow

Documentação Oficial de HTML Forms no W3C – World Wide Web Consortium.

Tipos Anônimos em C#

A utilização de tipos anônimos pode ser útil em diversas situações.
Fica a critério do desenvolvedor C#.

Utilizando um objeto com tipo anônimo:

var meuTipoAnonimo = new { IdProduto = 1, Descricao = "Produto1" };

Utilizando um array de objetos com tipo anônimo:

var arrayObjetos = new [] {
    new { IdProduto = 1, Descricao = "Produto 1"},
    new { IdProduto = 2, Descricao = "Produto 2"}
};

foreach (var produto in arrayObjetos)
{
   Console.WriteLine("Descrição Produto: {0}", produto.Descricao);
}

Ao utilizar um objeto tipado anonimamente, o editor de código do visual studio reconhece automaticamente os atributos do objeto.

Categorias:C#, Dicas / Tips Tags:, , , ,

Reiniciar MediaElement em WPF com C#

Se você está utilizando um MediaElement para exibir um vídeo na sua aplicação, e quer forçar a re-exibição do vídeo após clicar em um botão por exemplo, utilize o seguinte comando:

 

private void btnReiniciaVideo(object sender, MouseButtonEventArgs e)
        {
// onde mediaElementVideo é o component MediaElement
            mediaElementVideo.Position = new TimeSpan(0, 0, 0);
        }

Fica a dica.

Encontrando System.Runtime.Serialization.Json – Silverlight for Windows Phone

Olá Pessoal,
Desenvolvendo para Windows Phone com Silverlight me deparei com um problema, e compartilho a solução.

Se você precisar utilizar os recursos da biblioteca System.Runtime.Serialization.Json, mas adicionando referência para System.Runtime.Serialization não encontrar a classe Json.

Eis a solução:

Adicione referência para System.Servicemodel.Web.

Detectando se Visual Studio está aberto em modo debug

12 - 11 1 comentário

Olá pessoal.

Para detectar se o Visual Studio está aberto, em modo debug, atachado ao seu aplicativo, enquanto você estiver testando / debugando, utilize o comando:

 

    if (System.Diagnostics.Debugger.IsAttached)
       Messagebox.Show("Visual Studio aberto!");

Funciona em aplicativos Windows, Web e Mobile.

Erro ao alterar Default Namespace / Assembly Name

Se após alterar o Default Namespace ou Assembly Name de sua aplicação para Windows Phone 7, você recebe a exceção:

NullReferenceException, a solução é simples:

Linha de código que dispara a exceção: PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;

SOLUÇÃO: Na pasta do projeto exclua as pastas ” bin ”  e ” obj “, e recompile a sua aplicação.

Viagem e Voo

Dicas para viagens, férias e voos nacionais e internacionais

Ivan Guimarães Meirelles

Analista Desenvolvedor

Void Podcast

Vazio e sem retorno de valor

Elemar DEV

Negócios, tecnologia e desenvolvimento

2,000 Things You Should Know About WPF

Everything a WPF Developer Needs to Know, in Bite-Sized Chunks

Gabriel RB.net

Blog técnico, com dicas, códigos, novidades e problemas do dia-a-dia programando.

Alexandre Valente's Blog

Experiências em tecnologia e assuntos diversos

%d blogueiros gostam disto: