none
[RESOLVIDO] Alterar cor de um botão dentro de um GridView

    Question

  • Olá amigos, 

    Tenho um GridView que é preenchido com nome de equipamentos e com botões de ação dos equipamentos, que seriam Start e Stop.

    Gostaria de saber como que eu faço para mudar a cor do botão Start, por exemplo, quando eu clico para ligar o equipamento. 
    Cada vez que eu clicar no botão Start, ele muda a cor pra verde, por exemplo, e quando eu clico no botão Stop, voltar para a cor padrão.

    Segue abaixo a parte do código do sistema:

    Design

    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="c1tbl392" 
            DataSourceID="SqlDataSource1" EnableModelValidation="True">
            <Columns>
                <asp:BoundField DataField="c1tbl392" HeaderText="Equipamento" ReadOnly="True" SortExpression="c1tbl392" />
    
                <asp:TemplateField HeaderText="Start">
                    <ItemTemplate>
                        <asp:Button ID="BtnStartProcess" runat="server" CommandName="Start" Text="Start" Width="120px" 
                           OnCommand="BtnStartProcess" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "c1tbl392")%>' />
                    </ItemTemplate>
                </asp:TemplateField>
    
                <asp:TemplateField HeaderText="Stop">
                    <ItemTemplate>
                        <asp:Button ID="BtnStopProcess" runat="server" CommandName="Stop" Text="Stop" Width="120px" 
                            OnCommand="BtnStopProcess" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "c1tbl392")%>' />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

    CodeBehind StartProcess

    protected void BtnStartProcess(object sender, CommandEventArgs e)
            {
                string equip = e.CommandArgument.ToString();
    
                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.CreateNoWindow = false;
                startInfo.UseShellExecute = false;
                startInfo.FileName = @"c:\apl\LisConnect.exe";
                startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
                startInfo.Arguments = "-p -" + equip;
    
                Process exeProcess = Process.Start(startInfo);
            }

    CodeBehind StopProcess

            protected void BtnStopProcess(object sender, CommandEventArgs e)
            {
                //Busca processos no computador e encerra o selecionado
                Process[] exeProcess2 = Process.GetProcesses(Environment.MachineName);
    
                for (int i = 0; i < exeProcess2.Length; i++)
                {
                    if (exeProcess2[i].ProcessName.Contains("LisConnect"))
                    {
                        exeProcess2[i].Kill();
                        break;
                    }
                }
            }

    Estou me matando pra fazer isso, me parece simples, mas não está indo! rs

    Obrigado!


    Cleverson Darsie



    Friday, February 15, 2013 1:16 PM

Answers

  • Cara,

    Olha o meu código:

    aspx:

                    <asp:TemplateField>
                    <ItemTemplate>
                        <asp:Button ID="Button2" CommandName="Start" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" runat="server" Text="Stop" BackColor="Red" />
                    </ItemTemplate>
                    </asp:TemplateField>

    C#:

            protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
            {
                int index = int.Parse((string)e.CommandArgument);
    
                if (e.CommandName == "Start")
                {                                
                    Button btnGeral = (Button)GridView1.Rows[index].FindControl("Button2");
    
                    if (btnGeral.BackColor == System.Drawing.Color.Green)
                    {
                        btnGeral.BackColor = System.Drawing.Color.Red;
                        btnGeral.Text = "Stop";
                    }
                    else
                    {
                        btnGeral.BackColor = System.Drawing.Color.Green;
                        btnGeral.Text = "Start";
                    }
                }
            }

    Atenciosamente, Samuel dos Anjos

    Tuesday, February 19, 2013 8:05 PM
  • Cara,

    Me desculpe, utilize dessa forma no RowCommand:

    string strNome = GridView1.Rows[index].Cells[1].Text;   


    O índice informado no Cells[] é a posição da coluna, então por exemplo:

    CODIGO, NOME

    Possuo duas colunas sendo que os indices são 0 e 1. Quero pegar o nome:

    string strNome = GridView1.Rows[index].Cells[1].Text; 

    Lembrando que se você possuir o:

    <asp:CommandField ShowSelectButton="True" />

    Na sua gridview, isso vai contar como um índice, então não teríamos mais 0 e 1 e sim 0, 1 e 2


    Atenciosamente, Samuel dos Anjos

    Wednesday, February 20, 2013 10:16 PM

All replies

  • Coloca isso no evento clique do botão

    IDbotao.BackColor = System.Drawing.Color.Green;


    Friday, February 15, 2013 1:55 PM
  • Ruan, 

    Pelo botão estar dentro de um GridView, ele não aparece como Controle. Então não funciona essa possibilidade, já havia tentado.

    Mas obrigado mesmo assim.


    Cleverson Darsie

    Friday, February 15, 2013 2:05 PM
  • não custava tentar né rsrs

    Vê se isso aqui ajuda

    http://forum.imasters.com.br/topic/250646-como-mudar-a-cor-de-um-botao-alocado-numa-grid-view/

    Friday, February 15, 2013 2:09 PM
  • Ruan, 

    Essa opção que vc me passou pode ser que funcione, mas está acontecendo um erro que já procurei por aqui e não consegui resolver.

    Tive que criar um RowCommand, e quando clico no botão aparece o seguinte erro:

    + $exception {"Referência de objeto não definida para uma instância de um objeto."} System.Exception {System.NullReferenceException}

    Ainda não havia acontecido isso, o que será que fiz de errado?

    A unica coisa que mudei no código foi incluir isso:

    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
            {
                ((Button)GridView1.SelectedRow.FindControl("BtnStartProcess")).BackColor = System.Drawing.Color.Green;
            }


    Cleverson Darsie

    Friday, February 15, 2013 2:57 PM
  • Cara,

    Vamos lá, você já definiu o CommandName deles: Start e Stop. No seu RowCommand tente fazer o seguinte:

    if(e.CommandName == "Start") { Button btnGeral = (Button)sender;

    btnGeral.BackColor = System.Drawing.Color.Green; } else if(e.CommandName == "Start") { Button btnGeral = (Button)sender;

    btnGeral.BackColor = System.Drawing.Color.Green; }




    Atenciosamente, Samuel dos Anjos

    Friday, February 15, 2013 3:17 PM
  • Cara,

    Ignore o que eu disse, pois você vai ter problemas com o objeto sender. Se você conseguir pegar o indice da linha consegue sim trabalhar com o find control:

    Coloque o código abaixo no seu RowCommand novamente, e troque o nome da GridView1 pela sua grid e o Id do botão Button2 pelo o seu id de um dos botões.

                if (e.CommandName == "Start")
                {
                    for (int i = 0; i < GridView1.Rows.Count; i++)
                    {
                        Button btnGeral = (Button)GridView1.Rows[i].FindControl("Button2");
    
                        btnGeral.BackColor = System.Drawing.Color.Green;
    
                    }
                }

    Isso ai vai mudar a cor de todos os botões, porém é só um exemplo pois precisa pegar o indece apenas daquela linha que o botão está sem precisar fazer o for. Ficaria assim se você conseguir pegar o indice dentro do RowCommand:

                if (e.CommandName == "Start")
                {                
                    Button btnGeral = (Button)GridView1.Rows[index].FindControl("Button2");
    
                    btnGeral.BackColor = System.Drawing.Color.Green;
    
                }


    Atenciosamente, Samuel dos Anjos

    Friday, February 15, 2013 3:34 PM
  • Cara,

    Eu me lembro que se não passar o CommandArgument como faz acima no seu código, é possível pegar a linha da gridview por ele. Apenas tem que definir dessa forma o CommandArgument:

    <asp:Button ID="Button2" CommandName="Start" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" runat="server" Text="Button" />

    E no RowCommand utilizar assim:

                int index = int.Parse((string)e.CommandArgument);
    
                if (e.CommandName == "Start")
                {                
                    Button btnGeral = (Button)GridView1.Rows[index].FindControl("Button2");
    
                    btnGeral.BackColor = System.Drawing.Color.Green;
    
                }


    Atenciosamente, Samuel dos Anjos

    Friday, February 15, 2013 3:44 PM
  • Samuel, 

    Funcionou exatamente como preciso, agora preciso fazer o inverso, fazer com que o botão Stop volte a cor do botão Start para a padrão.

    Por enquanto com a ideia passada eu acho que vai dar certo.

    Qualquer duvida eu volto a perguntar aqui.

    Obrigado!


    Cleverson Darsie

    Friday, February 15, 2013 5:06 PM
  • Samuel, 

    Funcionou exatamente como preciso, agora preciso fazer o inverso, fazer com que o botão Stop volte a cor do botão Start para a padrão.

    Por enquanto com a ideia passada eu acho que vai dar certo.

    Qualquer duvida eu volto a perguntar aqui.

    Obrigado!


    Cleverson Darsie

    Bom, eu me enganei um pouco.

    Funcionou bem quanto a troca da cor dos botões, porém, o botão está vindo como índice e não com o nome do CommandArgument, como eu queria.
    Eu passo como argumento o nome do equipamento, e da forma que foi configurado agora, ele passa apenas o numero do botão, index. Ai meu equipamento não liga.

    Vou tentar com o código anterior ao ultimo que me enviou e ver se todos os botões vão trocar ao mesmo tempo, ou apenas o que for clicado.

    Obrigado!


    Cleverson Darsie

    Tuesday, February 19, 2013 7:19 PM
  • Samuel, 

    Funcionou exatamente como preciso, agora preciso fazer o inverso, fazer com que o botão Stop volte a cor do botão Start para a padrão.

    Por enquanto com a ideia passada eu acho que vai dar certo.

    Qualquer duvida eu volto a perguntar aqui.

    Obrigado!


    Cleverson Darsie

    Bom, eu me enganei um pouco.

    Funcionou bem quanto a troca da cor dos botões, porém, o botão está vindo como índice e não com o nome do CommandArgument, como eu queria.
    Eu passo como argumento o nome do equipamento, e da forma que foi configurado agora, ele passa apenas o numero do botão, index. Ai meu equipamento não liga.

    Vou tentar com o código anterior ao ultimo que me enviou e ver se todos os botões vão trocar ao mesmo tempo, ou apenas o que for clicado.

    Obrigado!


    Cleverson Darsie

    Bom, alterei para o código anterior ao que ultimo com index, e funcionou também, alterou somente a cor do botão clicado, e não de todos.

    Agora eu não estou conseguindo é fazer a troca, quando clicar no botão Stop, o botão Start voltar a ficar na cor padrão, que no caso é vermelho.

    Alguma sugestão?


    Cleverson Darsie

    Tuesday, February 19, 2013 7:36 PM
  • Cara,

    Passa o nome do equipamento em uma coluna da gridview ou no DataKeys, e quando for alterar a cor do botão, pegue esse nome do equipamento:

    Exemplos:

    string strNomeEquipamento = grdMinhaGrid.Rows[index].Cells["CelulaComoNome"].Text;
    
    //ou
    
    string strNomeEquipamento = grdMinhaGrid.DataKey[index]["NomeDadoParaDataKes"].ToString();
    
    E faça o que precisa com o nome do equipamento depois.
    
    ...


    Atenciosamente, Samuel dos Anjos


    Tuesday, February 19, 2013 7:40 PM
  • Cara,

    Você precisa fazer um if:

    Button btnStart= (Button)GridView1.Rows[index].FindControl("btnStart");
    
    Button btnStop= (Button)GridView1.Rows[index].FindControl("btnStop");
    
    
    if(btnStart.BackColor == System.Drawing.Color.Green)
    {
    
       btnStart.BackColor == //A cor default dele
       btnStop.BackColor = ...
    
    }
    else
    {
       btnStart.BackColor = System.Drawing.Color.Green
       btnStop.BackColor = ...
    }



    Atenciosamente, Samuel dos Anjos

    Tuesday, February 19, 2013 7:46 PM
  • Cara,

    Olha o meu código:

    aspx:

                    <asp:TemplateField>
                    <ItemTemplate>
                        <asp:Button ID="Button2" CommandName="Start" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" runat="server" Text="Stop" BackColor="Red" />
                    </ItemTemplate>
                    </asp:TemplateField>

    C#:

            protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
            {
                int index = int.Parse((string)e.CommandArgument);
    
                if (e.CommandName == "Start")
                {                                
                    Button btnGeral = (Button)GridView1.Rows[index].FindControl("Button2");
    
                    if (btnGeral.BackColor == System.Drawing.Color.Green)
                    {
                        btnGeral.BackColor = System.Drawing.Color.Red;
                        btnGeral.Text = "Stop";
                    }
                    else
                    {
                        btnGeral.BackColor = System.Drawing.Color.Green;
                        btnGeral.Text = "Start";
                    }
                }
            }

    Atenciosamente, Samuel dos Anjos

    Tuesday, February 19, 2013 8:05 PM
  • Samuel, 

    A parte de mudar a cor e iniciar o equipamento eu já consegui fazer.

    Só estou tendo problemas na hora de passar como parâmetro o nome do equipamento para que seja iniciado.

    No exemplo que vc me passou:

    string strNomeEquipamento = grdMinhaGrid.Rows[index].Cells["CelulaComoNome"].Text;
    
    //ou
    
    string strNomeEquipamento = grdMinhaGrid.DataKey[index]["NomeDadoParaDataKes"].ToString();

    Não está dando certo, pois diz que o argumento que estou passando para o Rows[index] é inválido. Tentei passar este argumento como int e como string, mas mesmo assim nenhum deu certo.

    Meu código está assim:

    int ind = int.Parse((string)e.CommandArgument);//e.CommandArgument.ToString();
                    string equip = GridView1.Rows[ind].Cells["c1tbl392"].Text;
    
                    System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                    startInfo.CreateNoWindow = false;
                    startInfo.UseShellExecute = false;
                    startInfo.FileName = @"c:\apl\LisConnect.exe";
                    startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
                    startInfo.Arguments = "-p -" + equip;

    Esta é a ultima parte, mas não estou conseguindo. Tentei de diversas formas, mas nada.
    Como dessa forma:

    for (int i = 0; i < GridView1.Rows.Count; i++)
                    {
                        GridViewRow row = GridView1.Rows[i];
                        string equip = GridView1.DataKeys[row.RowIndex].Value;
                    }

    Até agora, muito obrigado, tem ajudado muito!


    Cleverson Darsie



    Wednesday, February 20, 2013 2:00 PM
  • Cleverson tenho algo parecido com o que vc quer eu mudo a cor de um textbox em um gridview, eu uso datatable e ai eu mudo a cor do datatable e depois disso o datasource do gridview é o datatable funciona perfeito, tenho em vb mais basta vc adaptar

    Dim WL_OJBox As System.Web.UI.WebControls.TextBox Dim WL_OJDataGridItem As DataGridItem Dim WL_OJCor As System.Drawing.Color For Each WL_OJDataGridItem In GRD_UsuarioQuantidadeFixo.Items WL_OJBox = WL_OJDataGridItem.FindControl("meucampo") If Math.Round(CLng(WL_OJBox.Text.Trim) * CDbl(TXT_ValorTarifa.Text), 2) <> CDbl(GRD_UsuarioQuantidadeFixo.Items(I).Cells(5).Text) Then WL_OJBox.BackColor = WL_OJCor.Red WF_OJUsuarioQuantidadeFixo.Rows(I).Item("meucampo") = WL_OJBox.Text.Trim

    next



    Junior

    Wednesday, February 20, 2013 2:15 PM
  • Faz o seguinte no databound usa o findcontrol para achar seu button que vai dar certo.

    http://forums.asp.net/t/1096012.aspx/1


    Não esqueça de usar o componente </> na barra para posta seu código. Microsoft MCPD,MCTS,MCC

    Wednesday, February 20, 2013 3:01 PM
    Moderator
  • Seilor e Junior, 

    A parte de trocar a cor já está resolvido.
    Meu problema agora é como expliquei antes, quando vou passar o parâmetro para o equipamento, ele está indo com o Index que é pego pelo CommandArgument.
    Pelo ultimo exemplo que passei:

    for (int i = 0; i < GridView1.Rows.Count; i++)
    {
    	GridViewRow row = GridView1.Rows[i];
            string equip = GridView1.DataKeys[row.RowIndex].Value;
    }

    Consigo pegar o valor do Index que tem na coluna referente ao botão clicado, porém dessa forma ele está percorrendo o FOR todo, e me retornando para a variável equip o valor do ULTIMO equipamento na coluna, invés de me dar o nome do equipamento do botão clicado.

    Meu GridView está assim:

    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="c1tbl392" 
    	DataSourceID="SqlDataSource1" EnableModelValidation="True" OnRowCommand="GridView1_RowCommand" >
            <Columns>
            	<asp:BoundField DataField="c1tbl392" HeaderText="Equipamento" ReadOnly="True" SortExpression="c1tbl392" />
    
                    <asp:TemplateField HeaderText="Start / Stop">
                    	<ItemTemplate>
                            	<asp:Button ID="BtnStartStop" runat="server" CommandName="StartStop" Text="Start" Width="120px" 
                            		CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" BackColor="Green" />
                    	</ItemTemplate>
            	</asp:TemplateField>
    	</Columns>
    </asp:GridView>
    ....


    Cleverson Darsie


    Wednesday, February 20, 2013 3:49 PM
  • Cleverson,

    Tente isto

    O sender que eu me lembre é o controle que está mandando o evento, ou seja, o button.

    if (e.CommandName == "Start") { sender.BackColor = System.Drawing.Color.Red; sender.Text = "Stop"; }

               else
                    {
                        sender.BackColor = System.Drawing.Color.Green;
                        sender.Text = "Start";
                    }


    Wednesday, February 20, 2013 4:12 PM
  • Cleverson,

    Tente isto

    O sender que eu me lembre é o controle que está mandando o evento, ou seja, o button.

    if (e.CommandName == "Start") { sender.BackColor = System.Drawing.Color.Red; sender.Text = "Stop"; }

               else
                    {
                        sender.BackColor = System.Drawing.Color.Green;
                        sender.Text = "Start";
                    }


    Thiago, 

    Neste caso, o sender é um objeto, e não o controle button, portanto não funciona dessa maneira que vc falou.

    A parte de trocar a cor já está ok, o que quero agora é passar o parâmetro da coluna nome do equipamento como parâmetro.

    Obrigado.


    Cleverson Darsie

    Wednesday, February 20, 2013 5:32 PM
  • Cleverson,

    Tente isto

    O sender que eu me lembre é o controle que está mandando o evento, ou seja, o button.

    if (e.CommandName == "Start") { sender.BackColor = System.Drawing.Color.Red; sender.Text = "Stop"; }

               else
                    {
                        sender.BackColor = System.Drawing.Color.Green;
                        sender.Text = "Start";
                    }


    Thiago, 

    Neste caso, o sender é um objeto, e não o controle button, portanto não funciona dessa maneira que vc falou.

    A parte de trocar a cor já está ok, o que quero agora é passar o parâmetro da coluna nome do equipamento como parâmetro.

    Obrigado.


    Cleverson Darsie

    Concordo contigo em parte, sender é realmente um objeto, que você pode dar um cast para Button (esqueci de colocar no código). Se isso der certo você não precisa desse parâmetro.

    Use desta forma para não fazer tantos casts:

    Button button = (Button)sender;        if (e.CommandName == "Start")         {             button.BackColor = System.Drawing.Color.Red;            
    button.Text = "Stop";         }        else        {            button.BackColor = System.Drawing.Color.Green;           
    button.Text = "Start";        }        }


    Wednesday, February 20, 2013 6:44 PM
  • Thiago, 

    Eu acho que dessa forma não vai funcionar, pois o botão vem de um GridView, por isso que eu utilizo o CommandName.

    Quando eu coloco do jeito que vc passou aparece esse erro:

    Não é possível converter um objeto do tipo 'System.Web.UI.WebControls.GridView' no tipo 'System.Web.UI.WebControls.Button'.
    Eu já tinha conseguido fazer de outra forma, mas tem esse detalhe, o botão está num GridView.


    Cleverson Darsie

    Wednesday, February 20, 2013 6:57 PM
  • Cara,

    Me desculpe, utilize dessa forma no RowCommand:

    string strNome = GridView1.Rows[index].Cells[1].Text;   


    O índice informado no Cells[] é a posição da coluna, então por exemplo:

    CODIGO, NOME

    Possuo duas colunas sendo que os indices são 0 e 1. Quero pegar o nome:

    string strNome = GridView1.Rows[index].Cells[1].Text; 

    Lembrando que se você possuir o:

    <asp:CommandField ShowSelectButton="True" />

    Na sua gridview, isso vai contar como um índice, então não teríamos mais 0 e 1 e sim 0, 1 e 2


    Atenciosamente, Samuel dos Anjos

    Wednesday, February 20, 2013 10:16 PM
  • Perfeito Samuel!

    Agora está como eu gostaria!
    Muito obrigado.

    Mais um aprendizado.

    Cleverson Darsie

    Thursday, February 21, 2013 12:44 PM