Desenvolvedores.Net - TechBlog

Author Archives: Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Adicionar javascript na tag head

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (2 votos, média: 5,00 de 5)
Loading...
25 de julho de 2011

 Existem várias maneiras de se adicionar script dinamicamente em uma página html no lado servidor, aqui eu vou ensinar três delas.

A primeira e a mais simples é usando o ClientScriptManager que é uma classe para a manipulação de scripts do lado cliente

Vamos ao exemplo:

protected void Page_Load(object sender, EventArgs e)
{
	ClientScriptManager cs = Page.ClientScript;
	cs.RegisterClientScriptBlock(this.GetType(), "meuScript", "alert('Seja bem-vindo ao desenvolvedores.net');", true);
}

Este é o modo mais simples de se adicionar uma tag script. Vamos aos parâmetros.

No primeiro parâmetro informamos o tipo de objeto que iremos colocar o nosso script.

No segundo parâmetro informamos uma chave para identificar o nosso script.

No terceiro parâmetro informamos o nosso script.

No quarto parâmetro informamos que é para ser adicionado a tag <script>…</script>.

Usando esta técnica o script será adicionado no corpo do html, ou seja entre a tag <body>…</body>. Vejam o código gerado pelo asp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
	Untitled Page
</title></head>
<body>
    <form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGSCZayBSwoHn5bPS8BXxDJhk6Dhtg==" />
</div>

<script type="text/javascript">
//<![CDATA[
alert('Seja bem-vindo ao desenvolvedores.net');//]]>
</script>
    <div>
    </div>
    </form>
</body>
</html>

Ok! Interessante, e funciona. Mas em alguns casos eu preciso adicionar na tag <head>…</head>. Isto é interessante quando temos que declarar uma função que será executada por algum componente, ou quando queremos tratar algo antes do corpo da página ser montado. Então. Como devo proceder?

Neste caso temo que usar o objeto chamado HtmlGenericControl e definir seu tipo e atributos. Vamos ao exemplo:

protected void Page_Load(object sender, EventArgs e)
{
	HtmlGenericControl script = new HtmlGenericControl("script");
	script.Attributes.Add("type", "text/javascript");
	script.InnerHtml = "alert('Seja bem-vindo ao desenvolvedores.net');";
	this.Page.Header.Controls.Add(script);
}

Veja que definimos o tipo de objeto “script” e usamos o Attributes para definir a linguagem de script que vamos utilizar, e dentro da propriedade InnerHtml colocamos todo o código do nosso script.

Aqui o código gerado pela página, repare nas linhas em destaque que estão dentro da tag <head>…</head>.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
	Untitled Page
</title>
<script type="text/javascript">
alert('Seja bem-vindo ao desenvolvedores.net');
</script>
</head>
<body>
    <form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGSCZayBSwoHn5bPS8BXxDJhk6Dhtg==" />
</div>
    <div>
    </div>
    </form>
</body>
</html>

Bom. Mas eu uso um arquivo .js para organizar meus scripts, tem como eu fazer isso usando um arquivo?

A resposta é sim, tem como. Usando a mesma técnica descrita acima. Podemos adicionar um .js à nossa página. Vamos ao exemplo:

protected void Page_Load(object sender, EventArgs e)
{
	HtmlGenericControl script = new HtmlGenericControl("script");
	script.Attributes.Add("type", "text/javascript");
	script.Attributes.Add("src", "Arquivo.js");
	this.Page.Header.Controls.Add(script);
}

Repare que tiramos o InnerHtml e colocamos mais um atributo, o src , é aqui que definimos o caminho para o nosso arquivo .js.

abaixo o código gerado pela página. Repare nas linhas em destaque

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
	Untitled Page
</title>
<script type="text/javascript" src="Arquivo.js">
</script>
</head>
<body>
    <form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGSCZayBSwoHn5bPS8BXxDJhk6Dhtg==" />
</div>
    <div>
    </div>
    </form>
</body>
</html>

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Linq to Twitter

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (5 votos, média: 5,00 de 5)
Loading...
20 de julho de 2011

 Ola Pessoal. Hoje eu vou falar sobre uma biblioteca para recuperar os dados do twitter que é a LinqToTwitter.

Ela é fácil de trabalhar a documentação é boa e tem bastante exemplos de uso.

Então vamos lá. Mãos a obra.

Preparando o ambiente

Siga os passos abaixo na ordem descrita

Para que o twitter funcione de modo correto precisamos criar uma aplicação dentro do twitter. Este passo não é obrigatório caso você queira pegar apenas os tweets públicos, mas se desejar pegar de um usuário específico terá que usar os passos descritos abaixo.

  1.  Faça login na sua conta do twitter neste link https://dev.twitter.com/apps/new

  2. Uma página semelhante à esta deverá ter sido aberta para você: (Clique na miniatura para ver a

    imagem da tela.)
  3. Preencha os campos
    1. “Name” (Nome da  sua aplicação)
    2. “Description” (Descrição da sua aplicação)
    3. “WebSite” (Coloque a URL do seu site onde as pessoas irão acessar os tweets)
  4. Se você preencheu todos os dados corretamente uma página semelhante a esta será exibida. (Clique na miniatura para ver a imagem da página)

  5. Mantenha esta página aberta, pois iremos usar estas configurações.

Passos para criar o projeto

  1. Faça o download da dll Linq2Twitter. Link da versão que usamos no artigo http://linqtotwitter.codeplex.com/releases/view/69833.
  2. Descompacte o arquivo que você recebeu, lembre-se do diretório, você ira precisar dele 🙂
  3. Abra o Visual Studio e crie uma nova aplicação web
  4. Faça referencia à dll LinqToTwitter.dll, ela deverá estar no diretório onde você descompactou os arquivos no passo 2

Você não precisa ter uma conta no twitter para usar a DLL, só que neste caso você ira recuperar apenas os tweeters públicos

Código de exemplo para recuperar os tweets públicos:

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Data" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Linq To Twitter</title>

    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                var twitterCtx = new LinqToTwitter.TwitterContext();

                var publicTweets =
                    from tweet in twitterCtx.Status
                    where tweet.Type == LinqToTwitter.StatusType.Public
                    select tweet;

                System.Collections.Generic.List<object> data = new System.Collections.Generic.List<object>();

                publicTweets.ToList().ForEach(
                    tweet =>
                    {
                        data.Add(new { Nome = tweet.ScreenName, Mensagem = tweet.Text });
                    }
                    );

                grdTwitter.DataSource = data;
                grdTwitter.DataBind();

            }
            catch (Exception ex)
            {
                Context.Response.Write("Impossível conectar ao twitter<br/>" + ex.ToString());
            }
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView runat="server" ID="grdTwitter">
            <Columns>
            </Columns>
        </asp:GridView>
    </div>
    </form>
</body>
</html>

Ok! Agora queremos pegar um tweet de um determinado usuário. Como fazer?

Prestem bastante atenção aos comentários pelo código

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Data" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Linq To Twitter</title>

    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                //agora que temos uma aplicação cadastrada
                //temos que criar a autenticação ao twitter
                //primeiro criamos um objeto de autorização do tipo LinqToTwitter.SignInAuthorizer
                LinqToTwitter.SignInAuthorizer auth = new LinqToTwitter.SignInAuthorizer()
                {
                    //lembra daquele cadastro que fizemos no twitter?
                    //link:   https://dev.twitter.com/apps/new
                    //os dados que foram informados pelo twitter deverão ser informados aqui
                    //reparem que o mesmo nome da propriedade aqui é o mesmo nome da página do twitter.
                    //Não tem como errar.
                    Credentials = new LinqToTwitter.InMemoryCredentials()
                    {
                        ConsumerKey = "seu consumer key",
                        ConsumerSecret = "seu consumer secret",

                        //ATENÇÃO
                        //nesta propriedade informe o valor da página "Access token"
                        OAuthToken = "aqui vai o Access token",

                        //ATENÇÃO
                        //Nesta propriedade informe o valor da página "Access token secret"
                        AccessToken = "Aqui vai o Access token secret"
                    },

                    //estas podem manter como estão
                    UseCompression = true,
                    OAuthRequestTokenUrl = "https://api.twitter.com/oauth/request_token",
                    OAuthAccessTokenUrl = "https://api.twitter.com/oauth/access_token",
                    OAuthAuthorizeUrl = "https://api.twitter.com/oauth/authorize",
                };

                auth.Authorize();

                var twitterCtx = new LinqToTwitter.TwitterContext(auth);

                var publicTweets =
                    from tweet in twitterCtx.Status
                    where tweet.Type == LinqToTwitter.StatusType.User &&
                        tweet.ScreenName == "desenvolvedores"
                    select tweet;

                System.Collections.Generic.List<object> data = new System.Collections.Generic.List<object>();

                publicTweets.ToList().ForEach(
                    tweet =>
                    {
                        data.Add(new
                        {
                            Nome = tweet.ScreenName,
                            Mensagem = tweet.Text,
                            Site = tweet.User.URL,
                        });
                    });

                grdTwitter.DataSource = data;
                grdTwitter.DataBind();

            }
            catch (Exception ex)
            {
                Context.Response.Write("Impossível conectar ao twitter<br/>" + ex.ToString());
            }
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView runat="server" ID="grdTwitter">
            <Columns>
            </Columns>
        </asp:GridView>
    </div>
    </form>
</body>
</html>

Lembre-se: No twitter na tela que se configura o site você terá sempre que informar para qual site está liberado sua aplicação. Se não fizer isso, pode ser que não funcione quando você publicar sua aplicação.


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

SharpSVN

1
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (3 votos, média: 5,00 de 5)
Loading...
17 de julho de 2011

Eu sempre usei o Subversion pra controlar as versões de meus códigos e no começo deste mês tive a necessidade de desenvolver uma aplicação que recuperasse as revisões do SVN e disponibilizasse em um site para controle dos gerentes de um dos projetos.

Como ferramenta eu optei por usar o SharpSVN, uma biblioteca escrita  para .NET. Apesar do esforço não encontrei muita coisa em português então resolvi dar uma estudada na documentação (http://docs.sharpsvn.net/current) e escrever este artigo.

Aqui eu vou mostrar uma conexão simples e como resolver o seguinte erro ao publicar o site  “SharpSvn.SvnFormatException: Can’t determine the user’s config path“.

Então vamos lá. Mãos a obra.

Primeiramente temos que preparar o nosso ambiente, para isso temos que baixar os arquivos do SharpSVN http://sharpsvn.open.collab.net/files/documents/180/4381/SSvn-1.6016.1637.zip

Extraia os arquivos.

Abra o Visual Studio e cria uma nova aplicação Web.

Faça referência a dll SharpSvn.dll.

Eu vou recuperar as versões de um projeto que nós do desenvolvedores.net apoiamos e que está no Sourceforge

Página oficial do projeto: http://uninfe.com.br

Página no Sourceforge: https://uninfe.svn.sourceforge.net/svnroot/uninfe

E como sempre, prestem atenção aos comentários do código. Eu coloco informações úteis no mesmo.

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Exemplo SVN</title>

    <script runat="server" type="text/C#">
        protected void Page_Load(object sender, EventArgs e)
        {
            //definir o datasource do meu grid
            grdRevision.DataSource = LoadSvnRevision();

            //popular os dados no grid
            grdRevision.DataBind();
        }

        private System.Collections.Generic.List<object> LoadSvnRevision()
        {
            //inicar o cliente svm
            SharpSvn.SvnClient client = new SharpSvn.SvnClient();
            //aqui iniciamos o objeto que irá receber os dados de retorno do svn.
            //Obrigatoriamente tem que ser deste tipo System.Collections.ObjectModel.Collection<SharpSvn.SvnLogEventArgs>
            //pois o parâmetro é do tipo "out"
            System.Collections.ObjectModel.Collection<SharpSvn.SvnLogEventArgs> logItems = new System.Collections.ObjectModel.Collection<SharpSvn.SvnLogEventArgs>();

            //aqui chamamos o método responsável por trazer as revisões do SVN
            //no primeiro parâmetro informamos a url do repositório. (targetPath)
            //no segundo parâmetro informamos a nossa variável que irá receber o retorno
            client.GetLog(new Uri("https://uninfe.svn.sourceforge.net/svnroot/uninfe"), out logItems);

            //aqui eu crio uma variável que irá recuperar este retorno e converter
            //em uma lista de obejtos para ser usada dentro do meu grid
            System.Collections.Generic.List<object> data = new System.Collections.Generic.List<object>();

            foreach (var item in logItems) //aqui eu uso um array nomeado do tipo Key/Value
            {
                data.Add(new
                {
                    Id = item.Revision,
                    Autor = item.Author,
                    Data = item.Time,
                });
            }

            //descarrego cliente
            client.Dispose();

            //limpo da memória
            client = null;

            //retorno minha lista de dados
            return data;
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView runat="server" ID="grdRevision">
        </asp:GridView>
    </div>
    </form>
</body>
</html>

Assim temos uma aplicação básica que recupera os dados de um diretório publico. Mas, e se for em um diretório privado?

Basta acrescentar estas duas linhas ao seu código. Antes de chamar o método client.GetLog();

//Limpamos a autenticação antes de começar
client.Authentication.Clear();
//criamos uma autenticação de usuário usando o System.Net.NetworkCredential
client.Authentication.DefaultCredentials = new System.Net.NetworkCredential("Nome do usuário", "senha");

Uma outra dica que creio ser interessante passar é a opção de filtragem dos dados que iremos receber em nosso objeto de retorno. Do modo como foi feito no código de exemplo iremos recuperar todas as revisões, isso não é interessante em um projeto grande. Aqui vou ensinar a fazer o filtro por data.

//data de início do log que vamos buscar
//aqui informo +1 dia para que pegue também o dia atual
DateTime startDateTime = DateTime.Today.AddDays(1);

//iremos buscar 15 dias antes. Então informamos a segunda data
DateTime endDateTime = startDateTime.AddDays(-15);

//aqui iremos criar um "range" de datas para filtrar.
//para isso usamos o tipo SharpSvn.SvnRevisionRange
//o construtor do range aceita o tipo new SharpSvn.SvnRevision
//que por sua vez aceita vários tipos de filtros, um deles é o tipo data
//passamos então as datas de início e fim do range,
//de acordo com os parâmetros do contrutor do objeto SharpSvn.SvnRevisionRange
//primeiro e segundo parâmetro do construtor
SharpSvn.SvnRevisionRange range = new SharpSvn.SvnRevisionRange(new SharpSvn.SvnRevision(startDateTime), new SharpSvn.SvnRevision(endDateTime));

//criamos a nossa variável do tipo SharpSvn.SvnLogArgs para passar o nosso range de datas.
SharpSvn.SvnLogArgs args = new SharpSvn.SvnLogArgs(range);

//aqui chamamos o método responsável por trazer as revisões do SVN
//no primeiro parâmetro informamos a url do repositório. (targetPath)
//no segundo parâmetro passamos os argumentos de filtragem dos dados
//no terceiro parâmetro informamos a nossa variável que irá receber o retorno
client.GetLog(new Uri("https://uninfe.svn.sourceforge.net/svnroot/uninfe"), args, out logItems);

Preste atenção na linha em destaque, repare que modificamos o método client.GetLog() e passamos o parâmetro args que é o nosso filtro por data.

Vamos agora à um problema conhecido quando publicamos o nosso site.  “SharpSvn.SvnFormatException: Can’t determine the user’s config path“. Este erro não acontece no modo debug porque estamos executando nossa aplicação local e a nossa configuração de usuário já foi toda carregada. Mas quando publicamos podemos receber este erro, pois normalmente a aplicação web roda como um serviço no servidor e pode não ter toda a configuração de usuário carregada. Para isso temos que informar o caminho onde iremos salvar a configuração padrão do usuário. Podemos usar um caminho temporário ou um caminho fixo na sua aplicação. Fica a seu critério. Eu optei por executar eu um caminho temporário.

Para contornar este erro, iremos usar o método LoadConfiguration() que irá indicar onde iremos salvar o arquivo de configuração temporário.

client.LoadConfiguration(System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Svn"), true);

Atenção: Este método deve ser chamado antes de client.GetLog();

Abaixo o código completo de nossa aplicação SVN

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Exemplo SVN</title>

    <script runat="server" type="text/C#">
        protected void Page_Load(object sender, EventArgs e)
        {
            //definir o datasource do meu grid
            grdRevision.DataSource = LoadSvnRevision();

            //popular os dados no grid
            grdRevision.DataBind();
        }

        private System.Collections.Generic.List<object> LoadSvnRevision()
        {
            //inicar o cliente svm
            SharpSvn.SvnClient client = new SharpSvn.SvnClient();
            //aqui iniciamos o objeto que irá receber os dados de retorno do svn.
            //Obrigatoriamente tem que ser deste tipo System.Collections.ObjectModel.Collection<SharpSvn.SvnLogEventArgs>
            //pois o parâmetro é do tipo "out"
            System.Collections.ObjectModel.Collection<SharpSvn.SvnLogEventArgs> logItems = new System.Collections.ObjectModel.Collection<SharpSvn.SvnLogEventArgs>();

            //data de início do log que vamos buscar
            DateTime startDateTime = DateTime.Today.AddDays(1);

            //iremos buscar 15 dias antes. Então informamos a segunda data
            DateTime endDateTime = startDateTime.AddDays(-15);

            //aqui iremos criar um "range" de datas para filtrar.
            //para isso usamos o tipo SharpSvn.SvnRevisionRange
            //o construtor do range aceita o tipo new SharpSvn.SvnRevision que por sua vez aceita vários tipos de filtros, um deles é o tipo data
            //passamos então as datas de início e fim do range, de acordo com os parâmetros do contrutor do objeto SharpSvn.SvnRevisionRange
            SharpSvn.SvnRevisionRange range = new SharpSvn.SvnRevisionRange(new SharpSvn.SvnRevision(startDateTime), new SharpSvn.SvnRevision(endDateTime));

            //criamos a nossa variável do tipo SharpSvn.SvnLogArgs para passar o nosso range de datas.
            SharpSvn.SvnLogArgs args = new SharpSvn.SvnLogArgs(range);

            //aqui iremos dizer onde o arquivo de configuração do svn deverá ser salvo
            client.LoadConfiguration(System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Svn"), true);

            //aqui chamamos o método responsável por trazer as revisões do SVN
            //no primeiro parâmetro informamos a url do repositório. (targetPath)
            //no segundo parâmetro passamos os argumentos de filtragem dos dados
            //no terceiro parâmetro informamos a nossa variável que irá receber o retorno
            client.GetLog(new Uri("https://uninfe.svn.sourceforge.net/svnroot/uninfe"), args, out logItems);

            //aqui eu crio uma variável que irá recuperar este retorno e converter
            //em uma lista de obejtos para ser usada dentro do meu grid
            System.Collections.Generic.List<object> data = new System.Collections.Generic.List<object>();

            foreach (var item in logItems) //aqui eu uso um array nomeado do tipo Key/Value
            {
                data.Add(new
                {
                    Id = item.Revision,
                    Autor = item.Author,
                    Data = item.Time,
                });
            }

            //descarrego cliente
            client.Dispose();

            //limpo da memória
            client = null;

            //retorno minha lista de dados
            return data;
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView runat="server" ID="grdRevision">
        </asp:GridView>
    </div>
    </form>
</body>
</html>

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

CSharp com SQLite

5
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (4 votos, média: 4,00 de 5)
Loading...
2 de maio de 2011

Olá Pessoal.

Neste artigo eu vou falar sobre um banco de dados embarcado que eu acho muito prático de usar o nome dele é SQLite.

O que é o SQLite?

SQLite é uma biblioteca C que implementa um banco de dados SQL embutido. Programas que usam a biblioteca SQLite podem ter acesso ao banco de dados SQL sem executar um processo RDBMS separado.
SQLite não é uma biblioteca de cliente usada para conectar com um grande servidor de banco de dados. SQLite é o servidor.

A biblioteca SQLite lê e escreve diretamente para e do arquivo do banco de dados no disco.
O uso do SQLite é recomendado onde a simplicidade da administração, implementação e manutenção são mais importantes que incontáveis recursos que SGBDs mais voltados para aplicações complexas possivelmente implementam.

Entretanto situações onde a simplicidade é a melhor escolha são muito mais freqüentes do que pode-se imaginar.

Exemplos de uso do SQLite são:

  • Não restrito à sites (com menos de cem mil requisições por dia);
  • Dispositivos e sistemas embarcados;
  • Aplicações desktop;
  • Ferramentas estatísticas e de análise;
  • Aprendizado de banco de dados;
  • Implementação de novas extensões à SQL.

Não se recomenda o uso do SQLite para:

  • Sites com muitos acessos;
  • Grande quantidades de dados (talvez maior que algumas dúzias de gigabytes);
  • Sistemas com grande concorrência;
  • Aplicações cliente/servidor.

Algumas características do SQLite:

  • Software livre/domínio público e Multiplataforma;
  • Mecanismo de armazenamento seguro com transações ACID;
  • Não necessita de instalação, configuração ou administração;
  • Implementa a maioria do SQL92;
  • O Banco de Dados é guardado em um único arquivo;
  • Suporta bases de dados acima de 2 terabytes;
  • Sem dependências externas.

No artigo irei criar a base de dados e as tabelas “Programaticamente” (não achei uma palavra melhor para descrever isso.) mas se você quiser usar uma ferramenta recomendo o uso do SQLite Studio, é gratuita (http://sqlitestudio.one.pl/index.rvt)

Vou assumir que você já sabe o que é uma base de dados embarcada (embedded, embutido) e que tenha conhecimentos em C#.

Primeiramente temos que preparar o nosso ambiente. Para isso iremos fazer o download do provider para .NET. Descompacte o arquivo em uma pasta, iremos usar este caminho mais tarde.

Feito o download iremos criar um novo projeto do tipo windows form e chamar de SQLiteEmbedded.

Renomearemos o form1 para frmMain.

Vamos colocar seis botões em nosso form, segue os nomes e o texto para cada botão

Nome Botão Texto
btnCriarBase Criar Base
btnCriarTabelas Criar Tabelas
btnInsert Insert
btnUpdate Update
btnSelect Select
btnDelete Delete

Com estes botões iremos implementar as operações básicas, desde a criação da base de dados, criação das tabelas e a manipulação dos dados.

Iremos colocar agora um dataGridView e alguns campos de texto e data para montar o nosso form, não se preocupe com o form, ao final do artigo terá um link para download do projeto. Mas se quiser fazer o form.

A tela do meu form ficou assim:

Se quiser poupar trabalho, segue o código para colar no designer (frmMain.Designer.cs) troque o código que tem lá, por este.

namespace SQLiteEmbedded
{
    partial class frmMain
    {
        ///
        /// Required designer variable.
        ///
        private System.ComponentModel.IContainer components = null;

        ///
        /// Clean up any resources being used.
        ///
        /// <param name="disposing" />true if managed resources should be disposed; otherwise, false.
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        ///
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        ///
        private void InitializeComponent()
        {
            this.btnCriarBase = new System.Windows.Forms.Button();
            this.btnCriarTabelas = new System.Windows.Forms.Button();
            this.btnInsert = new System.Windows.Forms.Button();
            this.Update = new System.Windows.Forms.Button();
            this.btnDelete = new System.Windows.Forms.Button();
            this.dataGridView = new System.Windows.Forms.DataGridView();
            this.label1 = new System.Windows.Forms.Label();
            this.txtID = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.txtNome = new System.Windows.Forms.TextBox();
            this.txtTelefone = new System.Windows.Forms.TextBox();
            this.dtDataNascimento = new System.Windows.Forms.DateTimePicker();
            this.btnSelect = new System.Windows.Forms.Button();
            this.label5 = new System.Windows.Forms.Label();
            this.label6 = new System.Windows.Forms.Label();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
            this.SuspendLayout();
            //
            // btnCriarBase
            //
            this.btnCriarBase.Location = new System.Drawing.Point(12, 12);
            this.btnCriarBase.Name = "btnCriarBase";
            this.btnCriarBase.Size = new System.Drawing.Size(103, 23);
            this.btnCriarBase.TabIndex = 0;
            this.btnCriarBase.Text = "Criar Base";
            this.btnCriarBase.UseVisualStyleBackColor = true;
            this.btnCriarBase.Click += new System.EventHandler(this.btnCriarBase_Click);
            //
            // btnCriarTabelas
            //
            this.btnCriarTabelas.Location = new System.Drawing.Point(121, 12);
            this.btnCriarTabelas.Name = "btnCriarTabelas";
            this.btnCriarTabelas.Size = new System.Drawing.Size(103, 23);
            this.btnCriarTabelas.TabIndex = 1;
            this.btnCriarTabelas.Text = "Criar Tabelas";
            this.btnCriarTabelas.UseVisualStyleBackColor = true;
            this.btnCriarTabelas.Click += new System.EventHandler(this.btnCriarTabelas_Click);
            //
            // btnInsert
            //
            this.btnInsert.Location = new System.Drawing.Point(348, 51);
            this.btnInsert.Name = "btnInsert";
            this.btnInsert.Size = new System.Drawing.Size(75, 23);
            this.btnInsert.TabIndex = 2;
            this.btnInsert.Text = "Insert";
            this.btnInsert.UseVisualStyleBackColor = true;
            this.btnInsert.Click += new System.EventHandler(this.btnInsert_Click);
            //
            // Update
            //
            this.Update.Location = new System.Drawing.Point(348, 81);
            this.Update.Name = "Update";
            this.Update.Size = new System.Drawing.Size(75, 23);
            this.Update.TabIndex = 3;
            this.Update.Text = "Update";
            this.Update.UseVisualStyleBackColor = true;
            this.Update.Click += new System.EventHandler(this.Update_Click);
            //
            // btnDelete
            //
            this.btnDelete.Location = new System.Drawing.Point(348, 111);
            this.btnDelete.Name = "btnDelete";
            this.btnDelete.Size = new System.Drawing.Size(75, 23);
            this.btnDelete.TabIndex = 4;
            this.btnDelete.Text = "Delete";
            this.btnDelete.UseVisualStyleBackColor = true;
            this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click);
            //
            // dataGridView
            //
            this.dataGridView.AllowUserToAddRows = false;
            this.dataGridView.AllowUserToDeleteRows = false;
            this.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView.Location = new System.Drawing.Point(12, 182);
            this.dataGridView.Name = "dataGridView";
            this.dataGridView.ReadOnly = true;
            this.dataGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            this.dataGridView.Size = new System.Drawing.Size(537, 267);
            this.dataGridView.TabIndex = 6;
            this.dataGridView.SelectionChanged += new System.EventHandler(this.dataGridView_SelectionChanged);
            //
            // label1
            //
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(12, 51);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(21, 13);
            this.label1.TabIndex = 7;
            this.label1.Text = "ID:";
            //
            // txtID
            //
            this.txtID.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.txtID.Location = new System.Drawing.Point(96, 51);
            this.txtID.Name = "txtID";
            this.txtID.ReadOnly = true;
            this.txtID.Size = new System.Drawing.Size(100, 20);
            this.txtID.TabIndex = 8;
            //
            // label2
            //
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(12, 81);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(38, 13);
            this.label2.TabIndex = 9;
            this.label2.Text = "Nome:";
            //
            // label3
            //
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(12, 111);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(52, 13);
            this.label3.TabIndex = 10;
            this.label3.Text = "Telefone:";
            //
            // label4
            //
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(12, 141);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(70, 13);
            this.label4.TabIndex = 11;
            this.label4.Text = "Data Nascto:";
            //
            // txtNome
            //
            this.txtNome.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.txtNome.Location = new System.Drawing.Point(96, 81);
            this.txtNome.Name = "txtNome";
            this.txtNome.Size = new System.Drawing.Size(209, 20);
            this.txtNome.TabIndex = 12;
            //
            // txtTelefone
            //
            this.txtTelefone.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.txtTelefone.Location = new System.Drawing.Point(96, 111);
            this.txtTelefone.Name = "txtTelefone";
            this.txtTelefone.Size = new System.Drawing.Size(94, 20);
            this.txtTelefone.TabIndex = 13;
            //
            // dtDataNascimento
            //
            this.dtDataNascimento.CustomFormat = "dd/MM/yyyy";
            this.dtDataNascimento.Format = System.Windows.Forms.DateTimePickerFormat.Custom;
            this.dtDataNascimento.Location = new System.Drawing.Point(96, 141);
            this.dtDataNascimento.Name = "dtDataNascimento";
            this.dtDataNascimento.Size = new System.Drawing.Size(94, 20);
            this.dtDataNascimento.TabIndex = 14;
            //
            // btnSelect
            //
            this.btnSelect.Location = new System.Drawing.Point(348, 140);
            this.btnSelect.Name = "btnSelect";
            this.btnSelect.Size = new System.Drawing.Size(75, 23);
            this.btnSelect.TabIndex = 15;
            this.btnSelect.Text = "Select";
            this.btnSelect.UseVisualStyleBackColor = true;
            this.btnSelect.Click += new System.EventHandler(this.btnSelect_Click);
            //
            // label5
            //
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(12, 35);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(538, 13);
            this.label5.TabIndex = 16;
            this.label5.Text = "---------------------------------------------------------------------------------" +
                "--------------------------------------------------------------------------------" +
                "----------------";
            //
            // label6
            //
            this.label6.AutoSize = true;
            this.label6.Location = new System.Drawing.Point(12, 166);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(538, 13);
            this.label6.TabIndex = 17;
            this.label6.Text = "---------------------------------------------------------------------------------" +
                "--------------------------------------------------------------------------------" +
                "----------------";
            //
            // frmMain
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(561, 461);
            this.Controls.Add(this.label6);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.btnSelect);
            this.Controls.Add(this.dtDataNascimento);
            this.Controls.Add(this.txtTelefone);
            this.Controls.Add(this.txtNome);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.txtID);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.dataGridView);
            this.Controls.Add(this.btnDelete);
            this.Controls.Add(this.Update);
            this.Controls.Add(this.btnInsert);
            this.Controls.Add(this.btnCriarTabelas);
            this.Controls.Add(this.btnCriarBase);
            this.Name = "frmMain";
            this.Text = "SQLite Embededd";
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btnCriarBase;
        private System.Windows.Forms.Button btnCriarTabelas;
        private System.Windows.Forms.Button btnInsert;
        private System.Windows.Forms.Button Update;
        private System.Windows.Forms.Button btnDelete;
        private System.Windows.Forms.DataGridView dataGridView;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox txtID;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox txtNome;
        private System.Windows.Forms.TextBox txtTelefone;
        private System.Windows.Forms.DateTimePicker dtDataNascimento;
        private System.Windows.Forms.Button btnSelect;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Label label6;
    }
}

Ok! Feito isso iremos agora programar o código para cada um de nossos botões.

Para isso faça a referência à DLL System.Data.SQLite.dll. Procure pelo arquivo que você descompactou, aquele que você fez o download.

Primeiro vamos criar a base de dados.

Para criar o arquivo de base de dados usamos o método estático System.Data.SQLite.SQLiteConnection.CreateFile.

Clique 2x no botão “Criar Base”.  Segue o código do evento clique.

 private void btnCriarBase_Click(object sender, EventArgs e)
        {
            try
            {
                string dbFile = "sqlLite.db"; //a extensão pode ser a que você quiser
                if (System.IO.File.Exists(dbFile)) System.IO.File.Delete(dbFile);
                System.Data.SQLite.SQLiteConnection.CreateFile(dbFile);
                MessageBox.Show(this, "Base de dados criada com sucesso.", "Aviso!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, "Ocorreu um erro ao criar a base de dados.\n" +
                    ex.Message, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

OK! Agora que criamos a base de dados precisamos criar as tabelas. O SQLite aceita os comando de criação de tabelas, CREATE TABLE, ALTER TABLE, DROP TABLE. Então vamos criar a nossa tabela.

Antes de criar as nossas tabelas precisamos conhecer as strings de conexões que podemos ter para o SQLite.

Se você não definiu nenhuma senha para sua base de dados, esta string é o suficiente.

Data Source=caminho completo do arquivo;Version=3;

Caso tenha definido uma senha, use esta string

Data Source=caminho completo do arquivo;Version=3;Password=senha;

Clique 2x no botão “Criar Tabelas”. Segue o código do evento clique.

 private void btnCriarTabelas_Click(object sender, EventArgs e)
        {
            try
            {
                SQLiteConnection conn = OpenConnection();

                //criamos um objeto Command;
                SQLiteCommand command = conn.CreateCommand();

                //definimos o script de criação de tabelas
                string createTable = @"CREATE TABLE Pessoa (
                        ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
                        Nome VARCHAR(100) NOT NULL,
                        Telefone VARCHAR (30)
                    )";

                command.CommandText = createTable;
                command.ExecuteNonQuery();

                //aqui iremos fazer um alter table apenas para mostrar que é possível
                string alterTable = "ALTER TABLE Pessoa ADD Column DataNascimento DATE";

                command.CommandText = alterTable;
                command.ExecuteNonQuery();

                MessageBox.Show(this, "Tabela criada com sucesso.", "Aviso!", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
            catch (Exception ex)
            {
                MessageBox.Show(this, "Ocorreu um erro ao criar a tabela na base de dados.\n" +
                    ex.Message, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

Repare na linha em destaque o comando ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT aqui definimos que o campo ID será nossa chave primária do tipo inteiro e autoincremento. NO SQLite você não precisa definir a diretiva “AUTOINCREMENT“, pois por padrão toda chave primária do tipo inteiro é autoincremento. Mas, eu gosto de colocar.

Ok! Já criamos a nossa base de dados e já criamos a nossa tabela. Agora vamos manipular estes dados, para isso iremos codificar os botões btnInsert, btnUpdate, btnDelete e btnSelect.

Veja o código dos botões abaixo.

Botão btnInsert

private void btnInsert_Click(object sender, EventArgs e)
{
	if (!Validate(false)) return;

	SQLiteConnection conn = OpenConnection();
	SQLiteTransaction transaction = null;
	try
	{
		transaction = conn.BeginTransaction();
		SQLiteCommand command = conn.CreateCommand();
		string insertCommand = "INSERT INTO Pessoa (Nome, Telefone, DataNascimento) VALUES(?,?,?)";
		command.Parameters.Add("Nome", DbType.String).Value = txtNome.Text;
		command.Parameters.Add("Telefone", DbType.String).Value = txtTelefone.Text;
		command.Parameters.Add("DataNascimento", DbType.Date).Value = dtDataNascimento.Text;
		command.CommandText = insertCommand;
		command.ExecuteNonQuery();
		transaction.Commit();
		btnSelect.PerformClick();

	}
	catch (Exception ex)
	{
		if (transaction != null) transaction.Rollback();
		MessageBox.Show(this, "Ocorreu um erro ao inserir os dados na tabela.\n" +
						   ex.Message, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);

	}
	finally { conn.Close(); }
}

Botão btnUpdate


private void Update_Click(object sender, EventArgs e)
{
	if (!Validate(true)) return;

	SQLiteConnection conn = OpenConnection();
	SQLiteTransaction transaction = null;
	try
	{
		transaction = conn.BeginTransaction();
		SQLiteCommand command = conn.CreateCommand();
		string updateCommand = "UPDATE Pessoa SET Nome = ?, Telefone = ?, DataNascimento =? WHERE ID = ?";
		command.Parameters.Add("Nome", DbType.String).Value = txtNome.Text;
		command.Parameters.Add("Telefone", DbType.String).Value = txtTelefone.Text;
		command.Parameters.Add("DataNascimento", DbType.Date).Value = dtDataNascimento.Text;
		command.Parameters.Add("ID", DbType.Int32).Value = txtID.Text;
		command.CommandText = updateCommand;
		command.ExecuteNonQuery();
		transaction.Commit();
		btnSelect.PerformClick();

	}
	catch (Exception ex)
	{
		if (transaction != null) transaction.Rollback();
		MessageBox.Show(this, "Ocorreu um erro ao inserir os dados na tabela.\n" +
						   ex.Message, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);

	}
	finally { conn.Close(); }
}

Botão btnDelete

private void btnDelete_Click(object sender, EventArgs e)
{
	if (string.IsNullOrEmpty(txtID.Text) || Convert.ToInt32(txtID.Text) == 0)
	{
		MessageBox.Show(this, "Selecione um registro para excluir!", "Exluir!", MessageBoxButtons.OK, MessageBoxIcon.Information);
		return;
	}

	SQLiteConnection conn = OpenConnection();
	SQLiteTransaction transaction = null;
	try
	{
		transaction = conn.BeginTransaction();
		SQLiteCommand command = conn.CreateCommand();
		string deleteCommand = "DELETE FROM Pessoa WHERE ID = ?";
		command.Parameters.Add("ID", DbType.Int32).Value = txtID.Text;
		command.CommandText = deleteCommand;
		command.ExecuteNonQuery();
		transaction.Commit();
		btnSelect.PerformClick();
	}
	catch (Exception ex)
	{
		if (transaction != null) transaction.Rollback();
		MessageBox.Show(this, "Ocorreu um erro ao excluir os dados da tabela.\n" +
						   ex.Message, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);

	}
	finally { conn.Close(); }
}

Botão btnSelect

private void btnSelect_Click(object sender, EventArgs e)
{
	try
	{
		RefreshGrid();
	}
	catch (Exception ex)
	{
		MessageBox.Show(this, "Ocorreu um erro ao selcionar os registros.\n" +
						   ex.Message, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);

	}
	finally { }
}

Precisaremos também de alguns métodos que irão nos auxiliar no decorrer do processo.

Preste atenção aos comentários de cada método.

#region Métodos Auxiliares
///
/// abre uma conexão e retorna
///
///
private SQLiteConnection OpenConnection()
{
	string dbFile = "sqlLite.db";
	//criamos a conexão com a base de dados
	SQLiteConnection conn = new SQLiteConnection("Data Source=" + dbFile + ";Version=3;");
	//abrimos a conexão
	conn.Open();
	return conn;
}

///
/// atualiza a grid com os dados da base.
///
private void RefreshGrid()
{
	SQLiteConnection conn = OpenConnection();
	SQLiteCommand command = conn.CreateCommand();
	command.CommandText = "SELECT ID, Nome, Telefone, DataNascimento AS 'Data Nascto' FROM Pessoa";
	SQLiteDataReader rs = command.ExecuteReader();
	BindDataGrid(dataGridView, rs);
	conn.Close();
}

///
/// cria os campos da grid e prepara para exibir os dados da base
///
/// <param name="_dataGrid" />datagridview que deverá ser preparada
/// <param name="_rs" />recordset com os dados que deverão ser populados na grid
private void BindDataGrid(DataGridView _dataGrid, SQLiteDataReader _rs)
{
	_dataGrid.Rows.Clear();
	_dataGrid.Columns.Clear();

	for (int i = 0; i < _rs.FieldCount; i++)
	{
		DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
		col.HeaderText = _rs.GetName(i);
		col.Visible = true;
		col.Name = "col" + i;
		col.Resizable = DataGridViewTriState.True;
		_dataGrid.Columns.Add(col);
	}

	while (_rs.Read())
	{
		object[] row = new object[_rs.FieldCount];

		for (int i = 0; i < _rs.FieldCount; i++)
		{
			row[i] = FormatValue(_rs.GetValue(i), _rs.GetDataTypeName(i));
		}

		_dataGrid.Rows.Add(row);
	}
}

///
/// Formata um valor para ser exibido na grid
///
/// <param name="fieldValue" />valor do campo
/// <param name="fieldType" />tipo do campo
///
private object FormatValue(object fieldValue, string fieldType)
{
	string ret = "";

	if (fieldType.ToUpper() == "DATE")//só nos interessa o campo data para exemplo
		ret = string.Format("{0:dd/MM/yyyy}", fieldValue);
	else
		ret = fieldValue.ToString();

	return ret;
}

///
/// valida os dados do formulário e retorna
///
/// <param name="update" />se true valida o ID
///
new private bool Validate(bool update)
{
	if (string.IsNullOrEmpty(txtNome.Text))
	{
		MessageBox.Show(this, "Nome é obrigatório!", "Campo Obrigatório!", MessageBoxButtons.OK, MessageBoxIcon.Information);
		return false;
	}

	if (string.IsNullOrEmpty(txtTelefone.Text))
	{
		MessageBox.Show(this, "Telefone é obrigatório!", "Campo Obrigatório!", MessageBoxButtons.OK, MessageBoxIcon.Information);
		return false;
	}

	if (update)
	{
		if (string.IsNullOrEmpty(txtID.Text) || Convert.ToInt32(txtID.Text) == 0)
		{
			MessageBox.Show(this, "Selecione um registro para continuar!", "Registro!", MessageBoxButtons.OK, MessageBoxIcon.Information);
			return false;
		}
	}

	return true;
}
#endregion

Com isso apresentei a vocês o SQLite, com este tutorial você aprendeu tudo que é preciso para fazer uma aplicação usando esta base de dados embarcada.

Para saber mais sobre o SQLite Provider acesse o link http://system.data.sqlite.org

Para saber mais sobre o SQLite acesse o link http://sqlite.org/docs.html

Para saber mais sobre as strings de conexão para SQLite acesse o link http://www.connectionstrings.com/sqlite

Se tiver alguma dúvida, utilize o nosso fórum de C# link http://techblog.desenvolvedores.net/bbpress/forum.php?id=2

Download para o projeto de exemplo [download id=”15″]


É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Controlando Threads com Semáforos (C#)

9
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (4 votos, média: 4,00 de 5)
Loading...
21 de abril de 2011

Neste artigo irei abordar como podemos controlar as nossas threads em C#, seqüência de execução e controlar o número de threads que podemos executar, por vez, em nossa aplicação .

Para isso vou falar da classe Semáforo, namespace System.Threading.Semaphore.

Primeiro vamos estudar um pouco esta classe.

Podemos usar a classe semáforo para controlar um pool de threads em nossa aplicação, para isso existem 2 métodos que devemos entender, WaitOne() e Release().

WaitOne()

Este método deverá ser chamado logo no começo, para que a thread atual só entre em execução quando a outra thread estiver terminado.
Este método indica ao semáforo  que existe uma thread aguardando a execução e incrementa a contagem dentro do semáforo.

Release()

Este método deve ser chamado sempre que um thread for finalizada, ou quando se desejar liberar para que outra thread possa entrar em execução. Este método decrementa a contagem do semáforo;

 

Não existe uma garantia de que as threads serão executadas em FIFO (PEPS – Primeiro que Entra Primeiro que Sai) ou LIFO (UEPS – Ultimo que Entra Primeiro que Sai). Para isso temos que ter um controle das nossas threads.

A classe semáforo também não garante que ao chamar o método WaitOne() ou Release() a thread realmente possa ser executada.

Exemplo:

Se pegarmos duas threads X e Y, para a execução de Y temos que esperar X terminar. Caso haja algum erro em X e o método Release() não for chamado a thread Y nunca será executada.

Outro caso:

Para a execução de Y temos que esperar a thread X terminar, mas chamamos o método Release() logo no começo da thread e não no final. Isto fará com que a thread Y seja executada mesmo antes do término da thread X.

Outro erro que podermos ter é, se definirmos o nosso semáforo com o tamanho de três threads por execução e chamarmos o método Release() por mais de três vezes a exceção SemaphoreFullException será lançada.

Bom, chega de conversa. Vamos ver um código de exemplo.

No código abaixo irei mostrar como chamar as threads em ordem e aleatórias.

using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;

public class ExemploSemaforo
{
    //vamos usar um semáforo para limitar as threads.
    private static Semaphore Pool;

    //este flag é apenas para indicar que estamos na thread desordenada.
    // então temos que chamar o waitOne nos métodos
    private static bool flag = false;

    public static void Main()
    {
        Console.WriteLine("Programa Iniciado");

        ThreadOrdenada();

        ThreadAleatoria();

        Console.WriteLine("Aguarde as threads serem executadas");

        Console.ReadKey();
    }

    /// <summary>
    /// este método irá executar as threads em ordem de criação
    /// </summary>
    private static void ThreadOrdenada()
    {
        Console.WriteLine("Threads Ordenadas");

        //este buffer será criado para garantir que as threads
        //sejam executadas na ordem em que foram chamadas (criadas)
        //iremos usar ele mais abaixo para iniciar as nossas threads
        Queue<Thread> ThreadBuffer = new Queue<Thread>();

        //iniciamos o Pool

        //o primeiro parâmetro do Pool indica quantas threads temos liberadas para iniciar
        //o segundo parâmetro indica quantas threads podemos executar por vez
        Pool = new Semaphore(0, 1);

        //criando um Pool de threads que chamam o MetodoUm
        for (int i = 0; i < 5; i++)
        {
            Thread t = new Thread(new ThreadStart(MetodoUm));
            t.Name = "MetodoUm_Thread#" + i;
            ThreadBuffer.Enqueue(t);
        }

        //criando um Pool de threads que chamam o MetodoDois
        for (int i = 0; i < 5; i++)
        {
            Thread t = new Thread(new ThreadStart(MetodoDois));
            t.Name = "MetodoDois_Thread#" + i;
            ThreadBuffer.Enqueue(t);
        }

        //agora iremos iniciar todas as threads
        while (ThreadBuffer.Count > 0)
        {
            Thread t = ThreadBuffer.Dequeue();
            t.Start();

            //espera o fim da thread anterior para continuar
            //resolvi esperar aqui para garantir que qualquer thread que for executada
            //irá esperar a outra terminar.
            //se tirarmos esta linha as threads nao terão uma ordem definida para executar.
            Pool.WaitOne();//comente este linha e execute o programa novamente. Atente aos erros
        }
    }

    /// <summary>
    /// Este método chama as threads em qualquer ordem
    /// </summary>
    private static void ThreadAleatoria()
    {

        Console.WriteLine("Threads Aleatórias");

        flag = true;

        //iniciamos o Pool

        //o primeiro parâmetro do Pool indica quantas threads temos liberadas para iniciar
        //o segundo parâmetro indica quantas threads podemos executar por vez

        //repare que aqui, diferente da thread ordenada
        //o primeiro parâmetro é 3 para indicar que temos posições livres
        //o segundo é três para indicar que podemos executar até 3 por vez
        Pool = new Semaphore(3, 3);

        //criando um Pool de threads que chamam o MetodoUm
        for (int i = 0; i < 5; i++)
        {
            Thread t = new Thread(new ThreadStart(MetodoUm));
            t.Name = "MetodoUm_Thread#" + i;
            t.Start();
        }

        //criando um Pool de threads que chamam o MetodoDois
        for (int i = 0; i < 5; i++)
        {
            Thread t = new Thread(new ThreadStart(MetodoDois));
            t.Name = "MetodoDois_Thread#" + i;
            t.Start();
        }
    }

    private static void MetodoUm()
    {
        try
        {
            if (flag) Pool.WaitOne();

            Console.WriteLine("A thread " + Thread.CurrentThread.Name + " iniciou.");
            //espera 3 segundos antes de terminar
            Thread.Sleep(3000);

            if (Thread.CurrentThread.Name == "MetodoUm_Thread#1")
                throw new Exception("erro apenas para mostrar que não podemos esquecer de liberar o semáforo mesmo \nque haja erros...");

            Console.WriteLine("A thread " + Thread.CurrentThread.Name + " finalizou.");
        }
        catch (Exception ex)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(ex.Message);
            Console.ResetColor();
        }
        finally
        {
            //temos que sinalizar que a thread terminou.
            //isso é muito importante, não podemos esquecer, pois caso contrário
            //as outras threads não serão executadas
            Pool.Release();
        }
    }

    private static void MetodoDois()
    {
        try
        {
            if (flag) Pool.WaitOne();

            Console.WriteLine("A thread " + Thread.CurrentThread.Name + " iniciou.");
            //espera 3 segundos antes de terminar
            Thread.Sleep(3000);
            Console.WriteLine("A thread " + Thread.CurrentThread.Name + " finalizou.");

        }
        catch (Exception ex)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(ex.Message);
            Console.ResetColor();
        }
        finally
        {
            //temos que sinalizar que a thread terminou.
            //isso é muito importante, não podemos esquecer, pois caso contrário
            //as outras threads não serão executadas
            Pool.Release();
        }

    }
}

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Checar se a conexão com a internet está ativa

1
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (4 votos, média: 5,00 de 5)
Loading...
22 de março de 2011
Eu desenvolvi uma aplicação onde necessitava verificar a conexão com a internet, se estava ativa ou não, caso contrário a aplicação iria parar.Para verificar se a conexão com a internet está ativa podemos usar a API InternetGetConnectedState. Mais informações sobre a API e o parâmetro “Description” em
http://msdn.microsoft.com/en-us/library/aa384702(VS.85).aspx

Usando API:

[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

/// <summary>
/// verificar se está conectado à internet
/// </summary>
/// <returns>true se existir uma conexão</returns>
/// <remarks>retornar true não quer dizer que o destino esteja alcançável, utilize
/// IsReachable(url) para saber se o destino está alcançável</remarks>
public static bool IsConnectedToInternet()
{
	int Desc;
	bool ret = InternetGetConnectedState(out Desc, 0);
	return ret;
}

Mas neste caso se o método retornar true, isso não quer dizer que realmente podemos acessar o endereço web que precisamos. Por exemplo: Podemos estar conectados por um servidor proxy, onde precisamos fazer uma autenticação.

Neste caso temos que validar se nosso destino está alcançável, acessível.
Veja como:

/// <summary>
/// verifica se o destino informado está alcançável. (Acessível)
/// </summary>
/// <param name="_url">endereço URL</param>
/// <returns>true se estiver alcançável</returns>
public static bool IsReachable(string _url)
{
	System.Uri Url = new System.Uri(_url);

	System.Net.WebRequest webReq;
	System.Net.WebResponse resp;
	webReq = System.Net.WebRequest.Create(Url);

	try
	{
		resp = webReq.GetResponse();
		resp.Close();
		webReq = null;
		return true;
	}
	catch
	{
		webReq = null;
		return false;
	}
}

Se este método retornar true, aí sim podemos dizer que nossa aplicação tem acesso a internet.
Veja um exemplo em uma aplicação console.

static void Main(string[] args)
{
	if (IsConnectedToInternet())
	{
		Console.WriteLine("Conectado a internet");

		//mas...
		//estarmos conectado não quer dizer que podemos acessar o endereço que desejamos
		//para isto temos que validar se nosso destino é alcançável.
		if (IsReachable("http://desenvolvedores.net"))
			Console.WriteLine("temos acesso ao site http://desenvolvedores.net");
		else
			Console.WriteLine("não temos acesso ao site http://desenvolvedores.net");
	}
	else
		Console.WriteLine("Não está conectado a internet");

	Console.ReadKey();
}

Você poderia modificar a rotina IsConnectedToInternet e nela mesmo já validar se a conexão realmente está ativa. Para isso pode se usar um site que você tem certeza que estará sempre online. (Google, Microsoft, Desenvolvedores.net).

Veja a nova versão.

/// <summary>
/// verificar se está conectado a internet
/// </summary>
/// <returns>true se existir uma conexão</returns>
/// <remarks>retornar  true não quer dizer que o destino esteja alcançável, utilize
/// IsReachable(url) para saber se o destino está alcançável</remarks>
public static bool IsConnectedToInternet()
{
	int Desc;
	bool ret = InternetGetConnectedState(out Desc, 0);

	if (ret)
		ret = IsReachable("http://desenvolvedores.net");

	return ret;
}

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

: C#

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

MaskedNumber em C-Sharp

0
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (1 votos, média: 5,00 de 5)
Loading...
13 de março de 2011
Quando eu precisei de um campo numérico em C#, tentei usar o MaskedTexBox.Eu particularmente não gostei deste componente e neste caso eu reinventei a roda e acabei criando o MaskedNumber.

Eu coloquei alguns tipos já pré-formatados como:
Peso, Valor, Moeda, Porcentagem, Telefone, CPF, CNPJ, CEP e Custom

Pode ser que seja útil pra muita gente, pode ser que não. Mas está aí. Resolvi disponibilizar ele aqui para compartilhar com o pessoal.

Ainda tem alguns errinhos que vou corrigindo aos poucos e se alguém alterar os fontes e quiser me mandar as versões. Eu agradeço.

[]’s

Código do componente

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Threading;

public enum MaskedNumberFormat
{
    Peso,
    Valor,
    Moeda,
    Porcentagem,
    Telefone,
    CPF,
    CNPJ,
    CEP,
    Custom
}

namespace MaskedNumber
{
    public partial class MaskedNumber : System.Windows.Forms.TextBox
    {
        #region Construtores
        public MaskedNumber()
        {
            InitializeComponent();
            this.TextAlign = HorizontalAlignment.Right;
            base.KeyPress += new KeyPressEventHandler(MaskedNumber_KeyPress);
            base.LostFocus += new EventHandler(MaskedNumber_LostFocus);
            this.Format = MaskedNumberFormat.Valor;
        }
        #endregion

        #region Eventos
        void MaskedNumber_LostFocus(object sender, EventArgs e)
        {
            this.Refresh();
        }

        void MaskedNumber_KeyPress(object sender, KeyPressEventArgs e)
        {

            switch (e.KeyChar.ToString())
            {
                case ",":
                case ".":
                    e.KeyChar = ',';
                    if (this.Text.Contains(e.KeyChar.ToString()) == true)
                    {
                        e.Handled = true;
                        e.KeyChar = '0';
                    }
                    break;
                case "+":
                    e.Handled = true;
                    e.KeyChar = '0';

                    if (Format == MaskedNumberFormat.Telefone)
                    {
                        if (!this.Text.Contains("+"))
                        {
                            this.Text = "+" + this.Text;
                            this.SelectionStart = this.Text.Length;
                        }
                    }
                    break;

                case "-":
                    e.Handled = true;
                    e.KeyChar = '0';

                    if (Format == MaskedNumberFormat.Moeda ||
                        Format == MaskedNumberFormat.Valor ||
                        Format == MaskedNumberFormat.Porcentagem ||
                        Format == MaskedNumberFormat.Peso)
                    {
                        if (!this.Text.Contains("-"))
                        {
                            this.Text = "-" + this.Text;
                            this.SelectionStart = this.Text.Length;
                        }
                    }
                    break;
                default:
                    if (!char.IsNumber(e.KeyChar) &&    //numero
                        e.KeyChar != '\b')            //backspace
                    {
                        e.Handled = true;
                        e.KeyChar = '0';
                    }
                    break;
            }
        }

        private void MaskedNumber_Enter(object sender, EventArgs e)
        {
            this.SelectAll();
        }

        private void MaskedNumber_Click(object sender, EventArgs e)
        {
            this.SelectAll();
        }
        #endregion

        #region Propriedades
        private MaskedNumberFormat format;
        private String mCustomFormat = "0:0";
        public String CustomFormat
        {
            get
            {
                if (mCustomFormat == null ||
                    mCustomFormat.Length == 0) mCustomFormat = "0:0";
                return mCustomFormat;
            }
            set
            {
                mCustomFormat = value;
                this.Refresh();
            }
        }

        public MaskedNumberFormat Format
        {
            get { return format; }
            set
            {
                format = value;
                this.Refresh();
            }
        }

        public double Value
        {
            get
            {
                double ret = 0;
                double.TryParse(global::MaskedNumber.Format.OnlyNumbers(base.Text).ToString(), out ret);

                //se começar com ( é numero negativo
                if (Format == MaskedNumberFormat.Moeda && base.Text.StartsWith("("))
                    ret *= -1;
                return ret;
            }
        }

        #endregion

        #region Overrides and New
        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
                this.Refresh();
            }
        }

        public override void Refresh()
        {
            switch (Format)
            {
                case MaskedNumberFormat.Peso:
                    base.Text = String.Format("{0:n3}", this.Value);
                    break;
                case MaskedNumberFormat.Valor:
                    base.Text = String.Format("{0:n2}", this.Value);
                    break;
                case MaskedNumberFormat.Moeda:
                    base.Text = String.Format("{0:C}", this.Value);
                    break;
                case MaskedNumberFormat.Porcentagem:
                    base.Text = String.Format("{0:P2}", this.Value / 100);
                    break;
                case MaskedNumberFormat.CPF:
                    base.Text = global::MaskedNumber.Format.CPF(Text);
                    break;
                case MaskedNumberFormat.CNPJ:
                    base.Text = global::MaskedNumber.Format.CNPJ(Text);
                    break;
                case MaskedNumberFormat.CEP:
                    base.Text = global::MaskedNumber.Format.CEP(Text);
                    break;
                case MaskedNumberFormat.Telefone:
                    base.Text = global::MaskedNumber.Format.Telefone(Text);
                    break;
                case MaskedNumberFormat.Custom:
                    base.Text = global::MaskedNumber.Format.Custom(Text, CustomFormat);
                    break;
            }

            base.Refresh();
        }
        #endregion

        #region MaskedNumber.Designer.cs
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            //
            // MaskedNumber
            //
            this.Size = new System.Drawing.Size(150, 20);
            this.Enter += new System.EventHandler(this.MaskedNumber_Enter);
            this.Click += new System.EventHandler(this.MaskedNumber_Click);
            this.ResumeLayout(false);

        }

        #endregion
        #endregion
    }

    /// <summary>
    /// Classe responsável pelas formatações do componente.
    /// </summary>
    internal static class Format
    {
        /// <summary>
        /// Formata o CNPJ
        /// </summary>
        /// <param name="_cnpj">cnpj a ser formatado</param>
        /// <returns>cnpj formatado</returns>
        public static string CNPJ(string _cnpj)
        {
            MaskedTextProvider mascara;
            //cnpj
            //##.###.###/####-##
            mascara = new MaskedTextProvider(@"00\.000\.000/0000-00");
            mascara.Set(_cnpj);
            return mascara.ToString();
        }

        /// <summary>
        /// Formata o CPF
        /// </summary>
        /// <param name="_cpf">CPF a ser formatado</param>
        /// <returns>cpf formatado</returns>
        public static string CPF(string _cpf)
        {
            MaskedTextProvider mascara;
            //cpf
            //###.###.###-##
            mascara = new MaskedTextProvider(@"000\.000\.000-00");
            mascara.Set(_cpf);
            return mascara.ToString();
        }

        /// <summary>
        /// formata o cep e retorna
        /// </summary>
        /// <param name="_cep">cep a ser formatado</param>
        /// <returns>cep formatado como 00000-000</returns>
        public static string CEP(string _cep)
        {
            _cep = OnlyNumbers(_cep).ToString().Replace("-", "");
            _cep = _cep.ToString(null).PadRight(8, '0');
            return _cep.Substring(0, 5) + "-" + _cep.Substring(5, 3);
        }

        /// <summary>
        /// Formata um número de telefone e retorna o numero formatado
        /// </summary>
        /// <param name="value">número de telefone</param>
        /// <returns>telefone formatado</returns>
        public static string Telefone(string value)
        {
            if (String.IsNullOrEmpty(value)) return "";
            string mascara = "";
            value = value.Trim();
            if (value.StartsWith("0800") ||
                value.StartsWith("0300") ||
                value.StartsWith("0500") ||
                value.StartsWith("0900"))
                mascara = @"0000\-000\-0000";
            else if (value.StartsWith("+"))
                mascara = @"+00\(00\)0000\-0000";
            else if (value.Length == 7)
                mascara = @"000\-0000";
            else if (value.Length == 8)
                mascara = @"0000\-0000";
            else if (value.Length == 10)
                mascara = @"\(00\)0000\-0000";
            else if (value.Length == 11)
                mascara = @"\(000\)0000\-0000";
            else if (value.Length == 12)
                mascara = @"00\(00\)0000\-0000";
            else if (value.Length == 13)
                mascara = @"000\(00\)0000\-0000";
            else
                mascara = "0".PadLeft(value.Length, '0');

            MaskedTextProvider maskProvider;

            maskProvider = new MaskedTextProvider(mascara);
            maskProvider.Set(value);

            if (!maskProvider.MaskCompleted)
                return value;

            return maskProvider.ToString();
        }

        public static string Custom(string Text, string CustomFormat)
        {
            MaskedTextProvider mascara;
            mascara = new MaskedTextProvider(CustomFormat);
            mascara.Set(Text);
            return mascara.ToString();
        }

        /// <summary>
        /// extrair todo caracter não numérico do text, deixando apenas a virgula e os números
        /// <para>Permite número negativo</para>
        /// </summary>
        /// <param name="text">texto a ser tratado</param>
        /// <returns></returns>
        public static object OnlyNumbers(object text)
        {
            bool flagNeg = false;

            if (text == null || text.ToString().Length == 0) return 0;
            string ret = "";

            foreach (char c in text.ToString().ToCharArray())
            {
                if (c.Equals('.') == true || c.Equals(',') == true || char.IsNumber(c) == true)
                    ret += c.ToString();
                else if (c.Equals('-') == true)
                    flagNeg = true;
            }

            if (flagNeg == true) ret = "-" + ret;

            return ret;
        }
    }
}

Código do exemplo. Não esqueça de fazer referência ao componente se estiver criando ele em separado.
E não esquecer de colocar na mesma solução para depurar.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Teste
{
    //iniciar o sistema
    class StartUp
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMain());
        }
    }

    public class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            linkLabel1.Text = "Se vc alterar os fontes e achar que isto foi útil. Não esqueça de enviá-los para mim. :)" + '\r' + '\n';
            linkLabel1.Text += "Visite meu site : http://desenvolvedores.net" + '\r' + '\n';
            linkLabel1.Text += "E-mail : projetos@desenvolvedores.net";

            linkLabel1.Links.Add(108, 26, "http://desenvolvedores.net");
            linkLabel1.Links.Add(145, 51, "mailto:projetos@desenvolvedores.net?subject=MaskedNumber");

        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(e.Link.LinkData.ToString());
        }

        private void maskedNumber4_TextChanged(object sender, EventArgs e)
        {

        }

        private void maskedNumber4_Enter(object sender, EventArgs e)
        {
            maskedNumber4.Format = MaskedNumberFormat.Custom;
            maskedNumber4.CustomFormat = txtFormatoCustom.Text;
        }

        #region frmMain.Designer
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.label5 = new System.Windows.Forms.Label();
            this.linkLabel1 = new System.Windows.Forms.LinkLabel();
            this.label6 = new System.Windows.Forms.Label();
            this.label7 = new System.Windows.Forms.Label();
            this.txtFormatoCustom = new System.Windows.Forms.TextBox();
            this.label8 = new System.Windows.Forms.Label();
            this.label9 = new System.Windows.Forms.Label();
            this.label10 = new System.Windows.Forms.Label();
            this.label11 = new System.Windows.Forms.Label();
            this.maskedNumber8 = new MaskedNumber.MaskedNumber();
            this.maskedNumber7 = new MaskedNumber.MaskedNumber();
            this.maskedNumber6 = new MaskedNumber.MaskedNumber();
            this.maskedNumber5 = new MaskedNumber.MaskedNumber();
            this.maskedNumber4 = new MaskedNumber.MaskedNumber();
            this.maskedNumber3 = new MaskedNumber.MaskedNumber();
            this.maskedNumber2 = new MaskedNumber.MaskedNumber();
            this.maskedNumber1 = new MaskedNumber.MaskedNumber();
            this.maskedNumberValor = new MaskedNumber.MaskedNumber();
            this.SuspendLayout();
            //
            // label1
            //
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(10, 12);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(72, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Formato Valor";
            //
            // label2
            //
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(10, 36);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(111, 13);
            this.label2.TabIndex = 2;
            this.label2.Text = "Formato Porcentagem";
            //
            // label3
            //
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(10, 64);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(72, 13);
            this.label3.TabIndex = 4;
            this.label3.Text = "Formato Peso";
            //
            // label4
            //
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(10, 90);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(81, 13);
            this.label4.TabIndex = 6;
            this.label4.Text = "Formato Moeda";
            //
            // label5
            //
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(10, 315);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(73, 13);
            this.label5.TabIndex = 19;
            this.label5.Text = "Digite o Valor:";
            //
            // linkLabel1
            //
            this.linkLabel1.Location = new System.Drawing.Point(7, 372);
            this.linkLabel1.Name = "linkLabel1";
            this.linkLabel1.Size = new System.Drawing.Size(263, 75);
            this.linkLabel1.TabIndex = 21;
            this.linkLabel1.TabStop = true;
            this.linkLabel1.Text = "linkLabel1";
            this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
            //
            // label6
            //
            this.label6.AutoSize = true;
            this.label6.Location = new System.Drawing.Point(63, 266);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(157, 13);
            this.label6.TabIndex = 16;
            this.label6.Text = "Defina o formato para \"Custom\"";
            //
            // label7
            //
            this.label7.AutoSize = true;
            this.label7.Location = new System.Drawing.Point(10, 290);
            this.label7.Name = "label7";
            this.label7.Size = new System.Drawing.Size(48, 13);
            this.label7.TabIndex = 17;
            this.label7.Text = "Formato:";
            //
            // txtFormatoCustom
            //
            this.txtFormatoCustom.Location = new System.Drawing.Point(121, 286);
            this.txtFormatoCustom.Name = "txtFormatoCustom";
            this.txtFormatoCustom.Size = new System.Drawing.Size(150, 20);
            this.txtFormatoCustom.TabIndex = 18;
            this.txtFormatoCustom.Text = "000,00/00-00";
            //
            // label8
            //
            this.label8.AutoSize = true;
            this.label8.Location = new System.Drawing.Point(10, 200);
            this.label8.Name = "label8";
            this.label8.Size = new System.Drawing.Size(68, 13);
            this.label8.TabIndex = 12;
            this.label8.Text = "Formato CPF";
            //
            // label9
            //
            this.label9.AutoSize = true;
            this.label9.Location = new System.Drawing.Point(10, 226);
            this.label9.Name = "label9";
            this.label9.Size = new System.Drawing.Size(75, 13);
            this.label9.TabIndex = 14;
            this.label9.Text = "Formato CNPJ";
            //
            // label10
            //
            this.label10.AutoSize = true;
            this.label10.Location = new System.Drawing.Point(10, 174);
            this.label10.Name = "label10";
            this.label10.Size = new System.Drawing.Size(69, 13);
            this.label10.TabIndex = 10;
            this.label10.Text = "Formato CEP";
            //
            // label11
            //
            this.label11.AutoSize = true;
            this.label11.Location = new System.Drawing.Point(10, 133);
            this.label11.Name = "label11";
            this.label11.Size = new System.Drawing.Size(93, 13);
            this.label11.TabIndex = 8;
            this.label11.Text = "Formato Telefone:";
            //
            // maskedNumber8
            //
            this.maskedNumber8.CustomFormat = "{0:0}";
            this.maskedNumber8.Format = MaskedNumberFormat.Telefone;
            this.maskedNumber8.Location = new System.Drawing.Point(121, 133);
            this.maskedNumber8.Name = "maskedNumber8";
            this.maskedNumber8.Size = new System.Drawing.Size(150, 20);
            this.maskedNumber8.TabIndex = 9;
            this.maskedNumber8.Text = "0800-123-4567";
            this.maskedNumber8.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            //
            // maskedNumber7
            //
            this.maskedNumber7.CustomFormat = "{0:0}";
            this.maskedNumber7.Format = MaskedNumberFormat.CEP;
            this.maskedNumber7.Location = new System.Drawing.Point(121, 174);
            this.maskedNumber7.Name = "maskedNumber7";
            this.maskedNumber7.Size = new System.Drawing.Size(150, 20);
            this.maskedNumber7.TabIndex = 11;
            this.maskedNumber7.Text = "12345-678";
            this.maskedNumber7.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            //
            // maskedNumber6
            //
            this.maskedNumber6.CustomFormat = "{0:0}";
            this.maskedNumber6.Format = MaskedNumberFormat.CNPJ;
            this.maskedNumber6.Location = new System.Drawing.Point(121, 226);
            this.maskedNumber6.Name = "maskedNumber6";
            this.maskedNumber6.Size = new System.Drawing.Size(150, 20);
            this.maskedNumber6.TabIndex = 15;
            this.maskedNumber6.Text = "12.345.678/9012-34";
            this.maskedNumber6.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            //
            // maskedNumber5
            //
            this.maskedNumber5.CustomFormat = "{0:0}";
            this.maskedNumber5.Format = MaskedNumberFormat.CPF;
            this.maskedNumber5.Location = new System.Drawing.Point(121, 200);
            this.maskedNumber5.Name = "maskedNumber5";
            this.maskedNumber5.Size = new System.Drawing.Size(150, 20);
            this.maskedNumber5.TabIndex = 13;
            this.maskedNumber5.Text = "123.456.789-01";
            this.maskedNumber5.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            //
            // maskedNumber4
            //
            this.maskedNumber4.CustomFormat = "000,00/00-00";
            this.maskedNumber4.Format = MaskedNumberFormat.Custom;
            this.maskedNumber4.Location = new System.Drawing.Point(121, 315);
            this.maskedNumber4.Name = "maskedNumber4";
            this.maskedNumber4.Size = new System.Drawing.Size(150, 20);
            this.maskedNumber4.TabIndex = 20;
            this.maskedNumber4.Text = "123.45/67-89";
            this.maskedNumber4.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            this.maskedNumber4.TextChanged += new System.EventHandler(this.maskedNumber4_TextChanged);
            this.maskedNumber4.Enter += new System.EventHandler(this.maskedNumber4_Enter);
            //
            // maskedNumber3
            //
            this.maskedNumber3.CustomFormat = "{0:0}";
            this.maskedNumber3.Format = MaskedNumberFormat.Moeda;
            this.maskedNumber3.Location = new System.Drawing.Point(121, 90);
            this.maskedNumber3.Name = "maskedNumber3";
            this.maskedNumber3.Size = new System.Drawing.Size(150, 20);
            this.maskedNumber3.TabIndex = 7;
            this.maskedNumber3.Text = "R$ 1.253,56";
            this.maskedNumber3.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            //
            // maskedNumber2
            //
            this.maskedNumber2.CustomFormat = "{0:0}";
            this.maskedNumber2.Format = MaskedNumberFormat.Peso;
            this.maskedNumber2.Location = new System.Drawing.Point(121, 64);
            this.maskedNumber2.Name = "maskedNumber2";
            this.maskedNumber2.Size = new System.Drawing.Size(150, 20);
            this.maskedNumber2.TabIndex = 5;
            this.maskedNumber2.Text = "123,566";
            this.maskedNumber2.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            //
            // maskedNumber1
            //
            this.maskedNumber1.CustomFormat = "{0:0}";
            this.maskedNumber1.Format = MaskedNumberFormat.Porcentagem;
            this.maskedNumber1.Location = new System.Drawing.Point(121, 36);
            this.maskedNumber1.Name = "maskedNumber1";
            this.maskedNumber1.Size = new System.Drawing.Size(150, 20);
            this.maskedNumber1.TabIndex = 3;
            this.maskedNumber1.Text = "89,33%";
            this.maskedNumber1.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            //
            // maskedNumberValor
            //
            this.maskedNumberValor.CustomFormat = "{0:0}";
            this.maskedNumberValor.Format = MaskedNumberFormat.Valor;
            this.maskedNumberValor.Location = new System.Drawing.Point(121, 12);
            this.maskedNumberValor.Name = "maskedNumberValor";
            this.maskedNumberValor.Size = new System.Drawing.Size(150, 20);
            this.maskedNumberValor.TabIndex = 1;
            this.maskedNumberValor.Text = "34.897,34";
            this.maskedNumberValor.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            //
            // frmMain
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(283, 458);
            this.Controls.Add(this.label11);
            this.Controls.Add(this.maskedNumber8);
            this.Controls.Add(this.label10);
            this.Controls.Add(this.maskedNumber7);
            this.Controls.Add(this.label9);
            this.Controls.Add(this.maskedNumber6);
            this.Controls.Add(this.label8);
            this.Controls.Add(this.maskedNumber5);
            this.Controls.Add(this.txtFormatoCustom);
            this.Controls.Add(this.label7);
            this.Controls.Add(this.label6);
            this.Controls.Add(this.linkLabel1);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.maskedNumber4);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.maskedNumber3);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.maskedNumber2);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.maskedNumber1);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.maskedNumberValor);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "frmMain";
            this.Text = "Exemplo de uso do MaskedNumber";
            this.Load += new System.EventHandler(this.frmMain_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private MaskedNumber.MaskedNumber maskedNumberValor;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private MaskedNumber.MaskedNumber maskedNumber1;
        private System.Windows.Forms.Label label3;
        private MaskedNumber.MaskedNumber maskedNumber2;
        private System.Windows.Forms.Label label4;
        private MaskedNumber.MaskedNumber maskedNumber3;
        private System.Windows.Forms.Label label5;
        private MaskedNumber.MaskedNumber maskedNumber4;
        private System.Windows.Forms.LinkLabel linkLabel1;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.Label label7;
        private System.Windows.Forms.TextBox txtFormatoCustom;
        private System.Windows.Forms.Label label8;
        private MaskedNumber.MaskedNumber maskedNumber5;
        private System.Windows.Forms.Label label9;
        private MaskedNumber.MaskedNumber maskedNumber6;
        private System.Windows.Forms.Label label10;
        private MaskedNumber.MaskedNumber maskedNumber7;
        private System.Windows.Forms.Label label11;
        private MaskedNumber.MaskedNumber maskedNumber8;
        #endregion
    }
}

E para quem não quiser copiar e colar o código todo. Ai vai o link da solução para download.
[download id=”13″ format=”1″]

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Usando dll C# como um ActiveX/DLL

4
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (1 votos, média: 5,00 de 5)
Loading...
25 de fevereiro de 2011
Nem todas as linguagens suportam o acesso às classes, métodos e propriedades das DLL’s criadas em .NET de uma forma “automática”, “nativa”.
Muitas vezes temos a necessidade de disponibilizar estes acessos para linguagens que suportam o uso de ActiveX. (veja: http://pt.wikipedia.org/wiki/ActiveX)E isso é bem simples de se fazer em .NET. Vamos ver como.

Iremos criar um novo projeto do tipo Class Library no Visual Studio eu dei o nome de ActiveX (criativo não?).
Iremos criar uma classe chamada de “MinhaClasse” (minha criatividade para nomes está a mil hoje).
Primeiro vamos ver o código de MinhaClasse
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace ActiveX
{
    //define o tipo de interface da classe

    [ClassInterface(ClassInterfaceType.AutoDual)]

    //registra um identificador para a classe no registry
    [ProgId("ActiveX.MinhaClasse")]

    //faz com que todos os métodos e propriedades da classe sejam visíveis
    [ComVisible(true)]

    public class MinhaClasse
    {
        private string mPropriedade;

        public string MinhaPropriedade
        {
            get { return mPropriedade; }
            set { mPropriedade = value; }
        }

        public string MeuMetodo()
        {
            return "MeuMetodo";
        }

        //este método eu não quero que seja visível. Então somente pra ele eu uso o comvisible = false
        [ComVisible(false)] //este método não ira aparecer no VB6 por ex.
        public string MeuMetodoOculto()
        {
            return "MeuMetodoOculto";
        }
    }
}
Ok! Feito isso podemos compilar nossa classe, que não irá dar erro, mas também não vai funcionar, temos que marcar um checkBox mágico para que a DLL como um todo seja declarada como ActiveX.
Para isso vá em “Project” -> “Properties” -> Aba “Build” e marque a opção “Register for COM Interop”.
Veja na animação:
Feito isso, compilaremos novamente a nossa DLL. Mas também não iria funcionar só de compilar. 🙂
Como todo bom ActiveX que se preze temos que registrar.
Utilize a seguinte sintaxe:
para registrar :
%windir%\Microsoft.NET\Framework\XXX\RegAsm.exe “Caminho Completo do ActiveX.dll” /tlb
Onde XXX é a versão do seu framework
Pronto, agora sim podemos usar a nossa DLL como um activeX, para isso vamos usar o VBScript para criarmos o objeto e um arquivo HTML com java script como exemplo.
VBScript
Dim activex
set activex = CreateObject("ActiveX.MinhaClasse")
MsgBox activex.MeuMetodo
Agora em HTML com java script

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>

    <script language="javascript" type="text/javascript">
    function Load()
    {
        var activeX;
        activeX = new ActiveXObject("ActiveX.MinhaClasse");
        alert (activeX.MeuMetodo());
    }
    </script>

    <title>Testando ActiveX em .NET</title>
</head>
<body onload="Load();">
</body>
</html>
Este artigo foi apenas uma parte do que se é possível fazer, mas não podemos esquecer dos eventos e interfaces que nossas dlls podem ter.
Mas isso vai ficar para uma próxima vez. 🙂
É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Inno Setup – Alterando variáveis de ambiente

1
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (1 votos, média: 5,00 de 5)
Loading...
23 de fevereiro de 2011
Recentemente, no fórum, foi postada uma dúvida no fórum em relação a alterar as variáveis de ambiente pelo Inno Setup.Aproveitei a deixa para fazer uma postagem sobre isso.Fórum: http://techblog.desenvolvedores.net/bbpress/topic.php?id=11.

O Inno Setup pode ser baixado em http://www.jrsoftware.org/isdl.php é um ótimo gerador de instalador para suas aplicações e não deixa nada a desejar eu o uso desde sua segunda versão para instalar as minhas aplicações.

Para o artigo vou pegar como exemplo a variável Path, que foi a dúvida postada, mas isto serve para qualquer tipo de variável.

Para as versões NT/2000/XP/2003 e atuais. As variáveis de ambiente ficam na seguinte chave do registro.

Para máquina:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

Para o usuário:
HKEY_CURRENT_USER\Environment

Para as versões 95/98/Me, é necessário modificar o arquivo AUTOEXEC.BAT. Mas não vamos falar sobre isso aqui.

O caminho na chave do registro para Path é um valor do tipo REG_EXPAND_SZ.
Como a documentação do Inno Setup para o Registro afirma na seção, há uma maneira de acrescentar valores a esses elementos:


Em um valor do tipo expandsz, ou multisz, você pode usar uma constante especial chamada {OldData} no parâmetro ValueData. {OldData} será substituída com os dados anteriores do valor do registro. A constante {OldData} pode ser útil se você precisar acrescentar uma string para um valor já existente, por exemplo, {OldData}, {app}. Se o valor não existe ou o valor existente não é um tipo string, a constante {OldData} não será usada.

Original:

On a string, expandsz, or multisz type value, you may use a special constant called {olddata} in this parameter. {olddata} is replaced with the previous data of the registry value. The {olddata} constant can be useful if you need to append a string to an existing value, for example, {olddata};{app}. If the value does not exist or the existing value isn’t a string type, the {olddata} constant is silently removed.

Então, para acrescentar um caminho a uma seção do Registro podemos usar:

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo";

Onde C:\foo é o nosso caminho
Mas deste modo, isso iria repetir o caminho quando você instalar uma segunda vez, o que deve ser corrigido também. No Inno podemos usar uma função em pascal que retorne se a variável Path realmente precisa ser alterada ou não, para isso iremos usar o parâmetro Check

Veja:

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo"; Check: CheckKey('Path','C:\foo')

Vamos escrever a função CheckKey, esta função lê o valor do caminho original e verifica se o valor informado já está na chave do registro.

[Code]

//@param key: chave do registro a ser validada
//@param value: valor a ser procurado
function CheckKey(key:string; value: string): boolean;
var
OrigPath: string;
begin

if not RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
key, OrigPath)
then begin
//vai retornar true se o valor não existir
Result := True;
exit;
end;
// se existir, temos que procurar por ele na variável inteira
// A função Pos() retorna 0 se não encontrado
Result := Pos(';' + value + ';', ';' + OrigPath + ';') = 0;
end;

Código completo do script para estudo:

#define MyAppName "Desenvolvedores"
#define MyAppVersion "1.5"
#define MyAppPublisher "desenvolvedores.net"
#define MyAppURL "http://desenvolvedores.net"
#define MyAppExeName "desenvolvedores.exe"

[Setup]
AppId={{006DC1BE-0C38-46DF-AF73-CC79E3A1E9F4}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DisableDirPage=yes
DefaultGroupName={#MyAppName}
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes

[Languages]
Name: "portugues"; MessagesFile: "compiler:Languages\Portugues.isl"

[Registry]
Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};C:\foo"; Check: CheckKey('Path','C:\foo')

[Code]

//@param key: chave do registro a ser validada
//@param value: valor a ser procurado
function CheckKey(key:string; value: string): boolean;
var
  OrigPath: string;
begin

  if not RegQueryStringValue(HKEY_LOCAL_MACHINE,
    'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
    key, OrigPath)
  then begin
  //vai retornar true se o valor não existir
    Result := True;
    exit;
  end;
  // se existir, temos que procurar por ele na variável inteira
  // A função Pos() retorna 0 se não encontrado
  Result := Pos(';' + value + ';', ';' + OrigPath + ';') = 0;
end;

Chegamos ao fim do artigo. Desde modo podemos modificar as variáveis de ambiente que precisamos.
Mas isso é apenas uma pequena parte do que podemos fazer com o Inno Setup e acesso ao registro.

Uma ótima fonte de ajuda também é o FAQ do Inno http://www.jrsoftware.org/isfaq.php

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Polimorfismo (POO)

10
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (8 votos, média: 3,50 de 5)
Loading...
12 de fevereiro de 2011
Para um melhor entendimento deste Artigo veja o Índice (Programação Orientada a Objetos)
Iremos entrar agora em nosso último tópico sobre POO, e  muito interessante que é polimorfismo.Se você seguiu toda a trajetória do artigo sobre POO deve ter visto várias formas de polimorfismo (isso não foi um trocadilho) durante a leitura.

Vimos em:

Herança (POO)
Tipos Genéricos (Generics) (POO)
Abstração e Interface (POO)

Leia este artigo e depois do entendimento, volte a eles e tente identificar o uso do polimorfismo.

Aqui iremos abordar o polimorfismo de uma forma mais ampla e detalhada. Então vamos lá.

Polimorfismo

Etimologicamente, polimorfismo quer dizer:

1 Que se apresenta ou ocorre sob formas diversas.
2 Que assume ou passa por várias formas, fases etc.

Em orientação a objetos podemos dizer também que o objeto pode ter “vários comportamentos”.

Quando você chama um método ele pode se referir a qualquer objeto, por exemplo o método “Abrir()”, ele pode abrir uma tampa de garrafa, uma janela, uma porta, pode abrir alguma coisa.

Em polimorfismo é necessário que os métodos tenham a mesma assinatura, o mecanismo utilizado é o de redefinição de métodos (Overriding Definições – Intermediário (POO)) , não confundir com sobrecarga de métodos (Overload Definições – Intermediário (POO)).

Em polimorfismo podemos:

1 Instanciar objetos diferentes para um mesmo tipo.
2 Substituir condicionais com o polimorfismo.
3 Usar parâmetros que aceitam diferentes tipos de objetos desde que tenham a mesma herança de classes.

Vamos à alguns exemplos para reforçarmos as idéias.

Vamos criar nossas classes que servirão de base para todo o exemplo.

Iremos criar uma calculadora bem simples, que implemente as quatro operações básicas.

Classe Base

namespace Polimorfismo
{
    /// <summary>
    /// Classe base para efetuar os cálculos matemáticos
    /// </summary>
    abstract class CalculoMatematico
    {
        public virtual double Valor1 { get; set; }
        public virtual double Valor2 { get; set; }

        public abstract double Resultado();
    }
}

Multiplicação

namespace Polimorfismo
{
    class Multiplicacao : CalculoMatematico
    {
        public override double Resultado()
        {
            return Valor1 * Valor2;
        }
    }
}

Divisão

namespace Polimorfismo
{
    class Divisao : CalculoMatematico
    {
        public override double Resultado()
        {
            return Valor1 / Valor2;
        }
    }
}

Adição

namespace Polimorfismo
{
    class Adicao : CalculoMatematico
    {
        public override double Resultado()
        {
            return Valor1 + Valor2;
        }
    }
}

Subtração

namespace Polimorfismo
{
    class Subtracao : CalculoMatematico
    {
        public override double Resultado()
        {
            return Valor1 - Valor2;
        }
    }
}

Vamos agora ao primeiro exemplo.
Partindo de um mesmo tipo de objeto, podemos instanciar os outros tipos.
Mas para isso todos as classes devem implementar a mesma classe Pai.

namespace Polimorfismo
{
    class Program
    {
        static void Main(string[] args)
        {
            //veja que definimos o tipo
            //como CalculoMatematico
            CalculoMatematico calc;

            //aqui é criado como Adicao
            calc = new Adicao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(calc.Resultado().ToString("N2"));

            //aqui é criado como Divisao
            calc = new Divisao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(calc.Resultado().ToString("N2"));

            //aqui é criado como Subtracao
            calc = new Subtracao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(calc.Resultado().ToString("N2"));

            //aqui é criado como Multiplicacao
            calc = new Multiplicacao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(calc.Resultado().ToString("N2"));

            Console.ReadKey();
        }
    }
}

O nosso segundo item diz que podemos substituir condicionais com o uso de polimorfismo.
Será?
Vamos ver os exemplos abaixo, reparem bem na diferença entre os dois métodos da classe Calculadora

Definição da classe Calculadora:

namespace Polimorfismo
{
    public enum TipoCalculo
    {
        Adicao,
        Subtracao,
        Multiplicacao,
        Divisao
    }

    static class Calculadora
    {
        /// <summary>
        /// Neste método temos que informar o tipo
        /// de calculo que o mesmo irá fazer
        /// </summary>
        /// <param name="tipo">tipo do calculo feito</param>
        /// <param name="valor1">valor 1 para o calculo </param>
        /// <param name="valor2">valor 2 para o calculo</param>
        /// <returns>resultado da expressão</returns>
        public static double Calcular(TipoCalculo tipo, double valor1, double valor2)
        {
            double resultado = 0;

            //e aqui temos o condicional switch
            switch (tipo)
            {
                case TipoCalculo.Adicao:
                    resultado = valor1 + valor2;
                    break;
                case TipoCalculo.Subtracao:
                    resultado = valor1 - valor2;
                    break;
                case TipoCalculo.Multiplicacao:
                    resultado = valor1 * valor2;
                    break;
                case TipoCalculo.Divisao:
                    resultado = valor1 / valor2;
                    break;
                default:
                    throw new NotImplementedException("nunca poderá chegar aqui");
            }

            return resultado;
        }

        /// <summary>
        /// fazendo deste modo não precisamos
        /// utilizar nenhum condicional
        /// </summary>
        /// <param name="calc">tipo de calculo</param>
        /// <returns>resultado do calculo</returns>
        public static double Calcular(CalculoMatematico calc)
        {
            return calc.Resultado();
        }
    }
}

Exemplificando…

namespace Polimorfismo
{
    class Program
    {
        static void Main(string[] args)
        {
            //aqui vamos usar o condicional
            Console.WriteLine("Usando o Condicional");
            Console.WriteLine(Calculadora.Calcular(TipoCalculo.Adicao, 23, 34).ToString("N2"));
            Console.WriteLine(Calculadora.Calcular(TipoCalculo.Divisao, 23, 34).ToString("N2"));
            Console.WriteLine(Calculadora.Calcular(TipoCalculo.Multiplicacao, 23, 34).ToString("N2"));
            Console.WriteLine(Calculadora.Calcular(TipoCalculo.Subtracao, 23, 34).ToString("N2"));

            Console.WriteLine("".PadLeft(80, '-'));
            Console.WriteLine("Usando polimorfismo");
            //Aqui nao iremos usar o condicional.
            //substituiremos pelo uso do polimorfismo
            CalculoMatematico calc;

            //aqui é criado como Adicao
            calc = new Adicao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(Calculadora.Calcular(calc).ToString("N2"));

            //aqui é criado como Divisao
            calc = new Divisao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(Calculadora.Calcular(calc).ToString("N2"));

            //aqui é criado como Multiplicacao
            calc = new Multiplicacao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(Calculadora.Calcular(calc).ToString("N2"));

            //aqui é criado como Subtracao
            calc = new Subtracao();
            calc.Valor1 = 23;
            calc.Valor2 = 34;
            Console.WriteLine(Calculadora.Calcular(calc).ToString("N2"));

            Console.ReadKey();
        }
    }
}

Na classe Calculadora, além de exemplificarmos a substituição de um condicional com o uso do polimorfismo, ainda vimos a sobrecarga de métodos, temos dois métodos Calcular com assinaturas diferentes.

Para um melhor entendimento de sobrecarga recomendo a leitura do tópico Definições – Intermediário (POO).

E vimos também o item 3 que diz que podemos aceitar parâmetros de várias formas de objetos reparem que o método public static double Calcular(CalculoMatematico calc) aceitou os quatro tipos básicos.

Conclusão

Vimos o uso do polimorfismo em métodos, mas podemos usar a idéia em construtores, propriedades, no uso de Generics (Tipos Genéricos (Generics)), que podemos chamar de Polimorfismo Genérico.

Podemos citar rapidamente o uso de downcast (converter em uma classe mais específica) ,  upcast (definir em uma classe mais genérica).

namespace Polimorfismo
{
    class Program
    {
        static void Main(string[] args)
        {
            //definir objeto
            CalculoMatematico calc = new Adicao();
            calc.Valor1 = 22;
            calc.Valor2 = 33;

            //downcast (classe mais específica)
            Adicao adicao = (Adicao)calc;
            Console.WriteLine(adicao.Resultado());

            //upcast (classe mais genérica)
            calc = (CalculoMatematico)adicao;
            Console.WriteLine(calc.Resultado());

            Console.ReadKey();
        }
    }
}

Ver Índice

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Herança (POO)

6
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (6 votos, média: 4,83 de 5)
Loading...
29 de janeiro de 2011
Para um melhor entendimento deste Artigo veja o Índice (Programação Orientada a Objetos)

Herança

Iremos entrar agora em um tópico que teremos muito o que discutir. Tentarei ser o mais simples , claro e objetivo.
Mas antes de falarmos sobre herança, iremos falar sobre a hierarquia das classes.

Hierarquia

Quando vamos trabalhar com muitas classes, temos que ter em mente a hierarquia (ordem) que estas classes deverão seguir.

Por exemplo:

Não poderemos ter os filhos antes dos pais e antes dos avós. A hierarquia correta para este tipo de classe seria:

Avô -> Pai -> Filho



(quando ví esta imagem, não resisti. Serve perfeitamente para o exemplo de hierarquia)

Assim temos a hierarquia bem definida dentro de nossas classes.

Transformando isso em programação teríamos generalização e especialização.

Como foi visto, a classe mais ao topo da hierarquia é a generalização, enquanto a última classe é a mais especializada.
No diagrama de seqüencia abaixo, podemos ver que as classes mais a esquerda são as genéricas e as mais a direita são as especializadas.

Agora vamos tratar dos tipos de herança que podemos ter.

Herança de Implementação

A herança de implementação é aquela onde herdamos todo o código da classe Pai, não precisamos reescrever código para utilizá-lo, estamos falando de reutilização de código.

Caso desejamos subsitituir um método da classe pai devemos usar overriding, como foi discutido em Definição (Intermediário).

Creio que a herança de implementação é a mais usada, pois herda a assinatura e os métodos da classe pai.

Herança de Interface

Caso não conheçam Interface e Abstração leiam este tópico.

A herança de interface é útil quando precisamos:

  • agrupar as nossas classes dentro de um mesmo contexto;
  • Na programação genérica (veja: Tipos Genéricos (Generics) );
  • Outros que vocês irão descobrir com o tempo;

Na herança de interface apenas herdamos as assinaturas de métodos e propriedades ao contrário da herança de implementação que além de herdar  as assinaturas herdamos também seu código, logo, no caso da interface temos que escrever o código do método ou propriedade.

Agregação

A agregação define uma dependência fraca entre as classes, isto quer dizer que os outros objetos continuam existindo mesmo que o todo for removido.
Podemos dizer que uma classe agregada (o todo) é montada com um conjunto de componentes (as partes).

Como exemplo vamos usar um carro.
Em nosso carro (classe agregada, o todo) temos os componentes (as partes), rodas, portas, motor.
Se desmontarmos o carro, as partes (rodas, portas, motor) continuaram a existir e poderão ser usadas em outro carro.

Composição

A composição define uma dependência forte entre as classes, isto quer dizer que se o todo deixar de existir as suas partes também deixaram de existir.

Exemplo:
Uma revista em quadrinhos, ela é composta por suas páginas. Se o todo, a revista, deixar de existir, suas páginas não farão sentido.

Como outro exemplo podemos citar um pedido e seus itens. Esta ligação é forte, logo é uma composição. Os itens não fariam sentido sem o Pedido. Se excluirmos o pedido seus itens serão excluídos. (Isto não te lembra um relacionamento feito em definição de tabelas? 1 para n ON DELETE CASCADE).

Para finalizarmos vamos colocar um diagrama de classes e um código para reforçar a idéia.

Diagrama acima convertido em código:

Interface IPessoa

namespace Heranca
{
    /// <summary>
    /// esta é uma interface.
    /// Percebam que declaramos apenas os métodos,
    /// iremos usar neste caso a herança de interface
    /// </summary>
    interface IPessoa
    {
        void Dancar();
        DateTime DataNascimento { get; set; }
        void Envelhecer();
        void Falar();
        int Idade { get; }
        string Nome { get; set; }
        Sexo Sexo { get;  }
    }
}

Classe Pessoa

namespace Heranca
{
    public enum Sexo
    {
        NaoDefinido,
        Masculino,
        Feminino
    }

    /// <summary>
    /// esta classe é uma classe genérica pra todo tipo de pessoa.
    /// vejam que aqui iremos herdar a interface IPessoa,
    /// neste caso será uma herança de interface.
    /// Devemos escrever código para todo método e propriedade
    /// definido na interface.
    /// </summary>
    abstract class Pessoa : IPessoa
    {
        /// <summary>
        /// esta propriedade poderá ser sobreescrita
        /// nas classes filhas. mas não é obrigatória
        /// </summary>
        public virtual int Idade
        {
            get
            {
                int idade = DateTime.Now.Year - DataNascimento.Year;
                if (DateTime.Now.Month < DataNascimento.Month ||
                (DateTime.Now.Month == DataNascimento.Month &&
                DateTime.Now.Day < DataNascimento.Day))
                    idade--;
                return idade;
            }
        }

        public DateTime DataNascimento { get; set; }

        /// <summary>
        /// esta propriedade deverá obrigatoriamente ser declarada
        /// na classe pai
        /// </summary>
        public abstract Sexo Sexo { get; }

        public virtual String Nome { get; set; }

        public virtual void Envelhecer()
        {
            DataNascimento = DataNascimento.AddYears(1);
            Console.WriteLine("A pessoa envelheceu um ano.");
        }

        public virtual void Dancar()
        {
            Console.WriteLine("A pessoa está dançando");
        }

        public virtual void Falar()
        {
            Console.WriteLine(@"A pessoa disse: visitem
            http://desenvolvedores.net");
        }
    }
}

Classe Pai

namespace Heranca
{
    /// <summary>
    /// Aqui iremos herdar a classe pessoa.
    /// vejam que apenas escrevi a propriedade Sexo.
    /// Pois na classe pai (abstrata) estava definido
    /// que as filhas deveria escrever o código para sexo.
    /// Mas as outras propriedades e métodos serão herdados de pessoa
    /// </summary>
    class Pai : Pessoa
    {
        public override Sexo Sexo { get { return Sexo.Masculino; } }

        /// <summary>
        /// este método poderá ser sobreescrito nas classes filhas
        /// neste caso o pai está apenas brincando.
        /// Veremos ele sobreescrito na classe filha
        /// </summary>
        public virtual void Brincar()
        {
            Console.WriteLine("O pai está brincando");
        }
    }
}

Classe Filho

namespace Heranca
{
    /// <summary>
    /// aqui o filho herdou todas as características do pai
    /// </summary>
    class Filho : Pai
    {

        /// <summary>
        /// aqui iremos substituir o método Brincar
        /// </summary>
        public override void Brincar()
        {
            Console.WriteLine("O filho está brincando com seu pai.");
        }
    }
}

Classe Aluno

namespace Heranca
{
    /// <summary>
    /// mais um classe que herda de pessoa
    /// </summary>
    class Aluno : Pessoa
    {
        public override Sexo Sexo
        {
            get { return Sexo.Feminino; }
        }

        public int VerNota()
        {
            return new Random().Next(0, 10);
        }
    }
}

E finalmente o código escrito em uma aplicação do tipo console.
Atenção, prestem bastante atenção aos comentários, eles têm dicas importantes.

namespace Heranca
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
             * aqui vai um dica útil.
             * Cuidado ao declarar o seu tipo de objeto
             * pois as propriedades e métodos que você
             * irá visualizar depende do tipo declarado
             *
             * Vejam aqui, vou declarar como um objeto Pessoa
             * mas vou instanciar como um Aluno
             */

            Pessoa pessoaAluno = new Aluno();

            pessoaAluno.Nome = "Marcelo";

            /*
             * reparem que o método VerNota() só existe
             * na classe Aluno, logo na linha 17,
             * mesmo o objeto sendo instanciado como
             * new Aluno() seus métodos só existirão
             * através do seu tipo definido Pessoa
             */

            Console.WriteLine(pessoaAluno.Nome);

            /*
             * Mas, e se precisarmos acessar
             * os dados de Aluno?
             * Simplesmente faça um cast (conversão)
             * de um objeto para outro
             * Vejam:
             */

            Aluno aluno = pessoaAluno as Aluno;

            Console.WriteLine(aluno.VerNota());

            /*
             * A dica acima é válida tambem para os tipos
             * interfaces
             */

            IPessoa pessoaFilho = new Filho();
            pessoaFilho.Falar();

            Filho filho = pessoaFilho as Filho;
            filho.Brincar();

            /*
             * Abaixo um exemplo do override em filho
             */

            Pai pai = new Pai();

            //aqui chamamos o método brincar de Pai
            pai.Brincar();

            //aqui chamamos o método brincar que foi substituido
            Filho meuFilho = new Filho();
            meuFilho.Brincar();

            /*
             * Legal. Mas posso chamar o método
             * Brincar da classe base?
             */

            pai = filho as Pai;
            pai.Brincar();

            /*
             * Não. Não podemos.
             * Apesar da instrução acima não dar erro
             * o método que será chamado é sempre
             * o método substituído.
             *
             * Mas a afirmação acima não é 100% correta.
             * Se em nossa classe Filho o método tivesse
             * sido declarado assim:
             * public new void Brincar()
             * O método chamado seria o da classe Pai,
             * pois neste caso não substituimos o método
             * e sim criamos um novo.
             *
             * Vejam as duas declarações juntas para comparar
             *
             * public new void Brincar()
             * public override void Brincar()
             */

            Console.ReadKey();

        }
    }
}

Ver Índice

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s

Encapsulamento (POO)

1
1 Estrela2 Estrelas3 Estrelas4 Estrelas5 Estrelas (Sem votação.)
Loading...
17 de janeiro de 2011
Para um melhor entendimento deste Artigo veja o Índice (Programação Orientada a Objetos)

Entenda como encapsulamento o ato de proteger características de nossos objetos, isto quer dizer que o que não for público estará protegido de ação externa.

Como exemplo iremos pegar um motor. Não precisamos saber o funcionamento dele, apenas temos que saber que o método Ligar() da nossa classe Motor irá fazer com que o nosso motor entre em funcionamento.

Mas não precisamos saber quais componentes o método irá acessar, modificar ou criar para que o nosso motor entre em funcionamento.

O que o método ligar faz, não nos diz respeito, apenas usamos e sabemos que vai funcionar.

No conceito de orientação a objetos podemos proteger aquilo que não queremos que sofram intervenção, nossas variáveis locais, nossos métodos e atributos.

Os dados protegidos só podem ser alterados dentro dos métodos em que foram declarados ou dentro do objeto a que eles pertencem.

Exemplo:

namespace Desenvolvedores.Net.Encapsulamento
{
 public class Motor
 {
 /*
 * Aqui podemos apenas recuperar o valor de Ligado.
 * Mas percebam que para modificar o motor para Ligado
 * não iremos conseguir fazer isso pois a propriedade
 * está como Private, logo podemos dizer que está
 * encapsulada.
 * Só iremos conseguir modificar este valor
 * internamente, dentro desta classe.
 */
 public bool Ligado { get; private set; }

 public void Ligar()
 {
 //variável declarada localmente.
 //podemos dizer que está encapsulada dentro
 //do método Ligar e é acessível
 //somente dentro deste método
 bool temGasolina = TemGasolina();

 if (temGasolina)
 /*
 * aqui modificamos a propriedade Ligado para verdadeiro.
 * Veja que só podemos alterar por aqui ou outro
 * método dentro deste objeto e nunca externamente.
 */
 Ligado = true;
 }

 /*
 * Este método está encapsulado, pois está acessível apenas
 * dentro desta classe (objeto)
 */
 private bool TemGasolina()
 {
 return true;
 }

public override string ToString()
 {
 if (Ligado)
 return "O motor está ligado.";
 else
 return "O motor está desligado.";
 }
 }

 class Program
 {
 static void Main(string[] args)
 {
 Motor motor = new Motor();

 Console.WriteLine(motor.ToString());

 motor.Ligar();

 Console.WriteLine(motor.ToString());

 //se tentarmos forçar o motor a ser ligado iremos
 //receber um erro do compilador:
 //Erro em C#
 //The property or indexer 'Encapsulamento.Motor.Ligado'
 //cannot be used in this context because the
 //set accessor is inaccessible

 motor.Ligado = true;

 Console.ReadKey();
 }
 }
}

Ver Índice

É isso ai pessoal 🙂
Até o próximo
♦ Marcelo

About Marcelo

Nascido em Juruaia/MG em uma fazenda de criação de búfalos, e residindo na região Sul do Brasil. Trabalha com desenvolvimento de aplicações desde os 17 anos. Atualmente é Arquiteto Organizacional na Unimake Software. Para saber mais ... http://desenvolvedores.net/marcelo []'s
Page 4 of 5«12345»