Existem muitos artigos que explicam como adicionar controles a um DataGrid, que podem ser usados para representar e editar dados em um formato diferente de um EditBox comum. Porém, todos parecem requerer que o programador edite o HTML na(s) página(s) do .aspx, ao invés de utilizar apenas o código contido nos arquivos.cs Codebehind. No passado, tive que implementar muitos controles diferentes que poderiam ser utilizados para representar e editar controles em um DataGrid e agora demonstrarei a coluna template de CheckBox, com CheckBoxes vinculados, pois é o controle mais simples, porém, o mais utilizado além do EditBox e é utilizado para editar campos do tipo booleano.

Implementação do ITemplate

Antes de implementarmos a classe que será utilizada como uma coluna no DataGrid, teremos que criar uma classe derivada de ITemplate, que será utilizada para representar e ou editar os dados na grade. Na maior parte dos casos, uma classe diferente terá que ser definida para exibição e edição, por exemplo, contendo um controle label ou um controle edit box. Felizmente podemos utilizar o mesmo controle - um CheckBox – tanto para representar o estado booleano quanto para editá-lo.


public CheckBoxItem(bool editable)

{

    readOnly = (editable==true)?false:true;

}

Tratando o Evento DataBinding

Dado que o controle CheckBox deve representar os dados contidos no DataGrid, então teremos que manipular necessariamente o evento DataBinding, que será chamado uma vez para cada linha do DataGrid. Isto pode ser configurado na implementação do método InstantiateIn, que é o único método da interface de ITemplate.


void ITemplate.InstantiateIn(Control container)

{

    CheckBox box = new CheckBox();

    box.DataBinding += new EventHandler(this.BindData);

    container.Controls.Add(box);

}

Processando o Evento DataBinding

O tratador de evento do DataBinding é utilizado para configurar o estado do controle dependendo dos dados no DataGrid subjacente, bem como para configurar o estado editável, dependendo de estar sendo utilizado para visualizar os dados ou para editá-los.


public void BindData(object sender, EventArgs e)

{

    CheckBox box = (CheckBox) sender;

    DataGridItem container = (DataGridItem) box.NamingContainer;

    box.Checked = false;

    box.Enabled = (readOnly == true) ? false:true;

    string data = ((DataRowView) container.DataItem)[dataField].ToString();

    Type type = ((DataRowView)

    container.DataItem).DataView.Table.Columns[dataField].DataType;

    if (data.Length>0)

    {

        switch (type.ToString())

        {

        case "System.Boolean":

            if ( data == "True")

            {

                box.Checked = true;

            }

            break;

        default:

            break;

        }

    }

}

Coluna Template De CheckBox

A classe que será utilizada como a coluna no DataGrid, será derivada da classe System.Web.UI.WebControls.TemplateColumn. Adicionaremos objetos à classe de implementação de ItemTemplate na propriedade ITemplate para exibição e na propriedade EditItemTemplate para edição.


public CheckBoxColumn()

{

    // set the view one as readonly

    viewItem = new CheckBoxItem(false);

    this.ItemTemplate = viewItem as ITemplate;

    // let the edit check box be editable

    editItem = new CheckBoxItem(true);

    this.EditItemTemplate = editItem as ITemplate;

}

Adicionando o Column ao DataGrid

O penúltimo passo será adicionar a coluna ao próprio DataGrid. Dada a forma em que projetamos a classe, isto é muito simples, porque poderá ser utilizada no lugar de uma BoundColumn.


CheckBoxColumn checkCol = new CheckBoxColumn();

checkCol.HeaderText = "Boolean Field (Editable)";

checkCol.DataField = "Boolean";

...

DataGrid1.Columns.Add(checkCol);

Extraindo o Updated State

O último passo será extrair os próprios dados do controle, quando formos atualizar ou inserir uma linha. Novamente utilizaremos um método similar com o normalmente empregado, entretanto, em vez de um TextBox utilizaremos um CheckBox.


sqlUpdateCommand1.Parameters["@Boolean"].Value = ((CheckBox)e.Item.Cells[4].Controls[0]).Checked;

AutoPostBack e recepção do evento CheckedChanged

Recentemente nos foi indagado se era possível receber o evento CheckedChanged dos CheckBoxes contidos na coluna. Desde então, atualizamos o código para manipular o cenário em que temos um DataGrid com uma CheckGridColumn e é possível atualizar o campo de imediato.

Para adicionarmos uma coluna ao DataGrid que manipula este cenário, fazemos o seguinte:


CheckBoxColumn checkCol2 = new CheckBoxColumn(true);

checkCol2.HeaderText = "Boolean Field (Always Editable)";

checkCol2.DataField = "Boolean";

// this is our handler for all of the CheckBoxes CheckedChanged events

checkCol2.CheckedChanged += new EventHandler(this.OnCheckChanged);

...

DataGrid2.Columns.Add(checkCol2);

Agora, necessitamos manipular o evento para alterar a entrada do banco de dados, portanto, temos que extrair a informação relevante do DataGrid assim como o estado do CheckBox. O seguinte exemplo mostra como isto poderia ser feito:


private void OnCheckChanged(object sender, EventArgs e)

{

       CheckBox box = (CheckBox) sender;

       DataGridItem container = (DataGridItem) box.NamingContainer;

       // get our values

       sqlUpdateCommand1.Parameters["@Object_id"].Value =

          int.Parse(container.Cells[0].Text);

       sqlUpdateCommand1.Parameters["@Boolean"].Value = box.Checked;
...

}