segunda-feira, 21 de dezembro de 2009

Chamando função do lado servidor com Javascript

Ja vi em muitos lugares essa dúvida, e vi muitas soluções complicadas, explicações gigantes para resolver esse problema.
Aqui mostro de uma forma mais direta como resolver esse problema de chamar uma função C# por exemplo com Javascript.
Primeiro no código fonte de sua página adicione um método estático com o atributo WebMethod. Seu código ficará assim:

public partial class _Default : System.Web.UI.Page
{
     protected void Page_Load(object sender, EventArgs e)
     {

     }

     [System.Web.Services.WebMethod]
     public static void MeuMetodo()
     {
     }
}

Agora no seu html adicione um ScriptManager colocando EnablePageMethods="true" e logo abaixo dele adicione sua função javascript, ficando assim:

<form if="form1" runat="server">
    <asp:scriptmanager EnablePageMethods="true" runat="server"></asp:scriptmanager>
    <script type="text/javascript">
          function Metodo() {
                PageMethods.MeuMetodo();
          }
    </script>
    <button onclick="javascript:Metodo();">Clique</button>
</form>

Esse pequeno artigo mostra de maneira simples como chamar uma função que está do lado do servidor por Javascript.

Até a próxima.

quinta-feira, 22 de outubro de 2009

Command GridView

Nessa postagem comentarei um dos tópicos mais perguntados, como gerar um comando a partir de um botão que está no GridView e pegar um dado desejado.
Após criar um novo projeto Web Application, adicione um GridView à sua página:




Feito isos clique em Edit Columns, escolha button field e clique em Add, do lado direito procure por CommandName e coloque Click, como na imagem:





Agora crie uma classe como abaixo:

public class Campos
{
      public int Id{get;set;}
      public string Nome{get;set;}
      public string Sobrenome{get;set;}
}

No page_load da página escreva esse código:

protected void Page_Load(object sender, EventArgs e)
{
        List campos = new List();
        campos.Add(new Campos(){Id = 1, Nome = "Murilo", Sobrenome = "Gomes"});
        campos.Add(new Campos(){Id = 2, Nome = "Gabriel", Sbrenome = "Gomes"});

        GridView1.DataSource = campos;
        GridView1.DataBind();

        GridView1.RowCommand += new GridViewCommandEventHandler(GridView1_RowCommand);
}

Quando você rodar o programa o resultado será esse:





Agora vamos ao código para poder pegar o valor do ID, logo abaixo em que termina Page_Load escreva essa função:

void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
         if(e.CommandName == "Click")
        {
                 int indice = Convert.ToInt32(e.CommandArgument);
                 int id = Convert.ToInt32(GridView1.Rows[indice].Cells[1].Text);
        }
}

Pronto agora no id você sempre terá o valor do Id da linha em que o botão foi clicado.

Alguns conceitos, o CommandArgument te retorna o indice da linha que gerou o evento.
O e.CommandName retorna o nome do evento, nesse caso estamos querendo o command Click que nós demos o nome acima.

terça-feira, 29 de setembro de 2009

Funcionalidade de classe e membro static

Desde o último mês ando participando com grande frequência dos fóruns da msdn, e faz alguns dias que respondi uma dúvida da classe static. Porém ao responder as perguntas fui respondendo algumas coisas que não havia pensado sobre ela, como ocupação de memória, performance e velocidade.
Estou aqui para mostrar como foi a discussão porém como uma explicação.
O que é um membro static? Um menbro static é um membro de uma classe que terá o mesmo valor em todas as partes do código, por exemplo, considere uma classe

class MinhaClasse
{
public int Valor;
public static int ValorCompartilhado;
}

Qual a diferença entre Valor e ValorComparilhado? É o seguinte se você fizer:

MinhaClasse c = new MinhaClasse();
c.Valor = 2;

O 2 comente será visível para a instância c, agora caso você faça MinhaClasse.ValorCompartilhado = 2 o 2 será visível em todo o programa e em todas as partes que você faça int v = MinhaClasse.ValorCompartilhado a v será atribuido 2.

O que é uma classe static? Uma classe static só poderá conter membros static, assim no exemplo anterior teríamos que mudar int Valor para static int Valor.

Quando usar uma classe ou membro static? Primeiro vou responder a membors static, fica óbvio que se você precisa utilizar uma mesma instancia ou valor em todo o programa, imagine por exemplo uma instancia de uma conexão com o banco, você usará uma instancia dessa conexão como static. E classe? Classe static é muito utilizado para classes que contém apenas métodos ou então àquelas em que você após analisar verá que todos seus membros ficariam melhor como static, pois seus valores são compartilhados em todo o programa.

Discutiremos agora a parte de memória, desempenho e velocidade, para isso vamos levar em consideração estas duas classe:

public static class ClasseStatic
{
private static OutraClasse oc = new OutraClasse();
public static int Calculo = oc.Calcular();
public static string Nome = oc.RetornaNome();
}

public class ClasseNaoStatic
{
private OutraClasse oc = new OutraClasse();
public int Calculo = oc.Calcular();
public string Nome = oc.RetornaNome();
}

O que a OutraClasse faz não nos importa, analisaremos outras coisas.

Memória:
Considerando a classe static nós teremos:
OutraClasse = 1
int = 1
string = 1

Agora considerando a classe não static nós teremos os dados acima a cada nova instancia dela, fazendo então por exemplo:
ClasseNaoStatic ns1 = new ClasseNaoStatic();
ClasseNaoStatic ns2 = new ClasseNaoStatic();
Você terá:
OutraClasse = 2
int = 2
string = 2

Tendo assim um consumo menor de memória para a classe static.

Performance e velocidade:
Como chamamos dois métodos da classe OutraClasse para atribuir a Calculo e Nome e considerando uma velocidade para este método retornar, então teremos um tempo menor para a classe static, e levando a atribuição na pilha de métodos podemos ver uma melhor performance na classe static também.

Por que então não usar sempre static?
Imgine a seguinte situação, uma classe que controla quais usuários estão usando seu sistema, se for static e cada vez que um novo usuário entrar no sistema, você atribuir seu nome por exemplo ao membro static, você perderá os outros pois todo o programa agora usará o novo valor.

Conclusão:
Use static quando você ver a necessidade de seus dados terem o mesmo valor em todo o programa e uma mudança nele afete também todo o programa.

Para ver como foi a discussão no fórum segue o link:
http://social.msdn.microsoft.com/Forums/pt-BR/vscsharppt/thread/95bf6774-0d70-4cec-b1bd-20b9eeb4d030

segunda-feira, 31 de agosto de 2009

Usando javascript para percorrer Repeater

Hoje entrei em uma situação na qual nunca tinha passado, me pediram para fazer uma função em javascript para percorrer os checkbox de um repeater e analisar se pelo menos um estava checado.
O único problema é que o Visual Studio gera código pra você sobrescrevendo o nome e o id que você deu quando se usa usercontrol, assim um name="chkPassenger" se tranformou em: mUsrMain_UsrWebCheckInPassengersByFlight1_rptPNRSegments_ctl00_rptPassengers_ctl02_chkPassenger,
tudo bem ele gerou um span com o name correto, mas eu queria encontrar diretamente o checkbox.
A solução foi escrever este código:

function GetAllCheckBox()
{
var count = 0;
var inputs = document.getElementsByTagName('input');
for(var i = 0; i < inputs.length; i++)
{
      if(inputs[i].type == 'checkbox' && inputs[i].name.indexOf('chkPassenger') != -1)
     {
            if(inputs[i].checked == true)
            {
                   count++;
                   break;
            }
     }
}

if(count == 0)
      return false;
return true;
}

O porque do return? Bem como este evento estava sendo gerado por um itemcommand ele estava dando postback e claro, se eu precisava fazer em javascript era justamente para evitar ele. Para cancelar um postback, adicione a seguinte propriedade no controle que gerará ele:

OnClienteClick="return GetAllCheckBox();"

Assim se retornar false ele cancelará o postback, caso contrário o postback ocorrerá normalmente.

terça-feira, 25 de agosto de 2009

Adicionando imagens no Crystal Report

Uma das coisas mais comuns a se fazer em software, é a possibilidade de fazer um resumo de vendas para que o usuário possa escolher entre salvar em diversos formatos ou então imprimir.
Para que isso seja feito com facilidade, Visual Studio possui além dos modelos de documentos da Microsoft, uma ferramenta poderosa chamada Crystal Report.
Infelizmente o Crystal Report não possui um campo mapeado para imagem, onde você possa adicionar apenas uma url e ele faça todo o trabalho para você. Você pode estar pensando "mas também o que mais ele quer?", porém isso é comum quando se trabalha com a classe Image do .NET.
Para realizar esse trabalho é necessário adicionar um array de bytes.

Em seu datasource crie um atributo byte[] por exemplo:

    public byte[] Image { get; set; }

Feito isso de um refresh no seu datasource no Crystal Report para que você possa visualizar o novo campo, após visualizado apenas arraste o novo campo para o report.

Adicione o namespace: using System.IO;

Agora para ler a imagem de seu disco adicione o seguinte código:

    FileStream stream = new FileStream(url, FileMode.Open, FileAccess.Read);
    BinaryReader reader = new BinaryReader(stream);
    suaClasse.Image = reader.ReadBytes(Convert.ToInt32(stream.Length));
    reader.Close();
    stream.Close();

Vincule o datasource do Crystal Report para uma lista de sua classe ou o seu dataset e então o Crystal Report poderá realizar o trabalho para você.