Usuário com melhor resposta
Controles Dinâmicos (Templates GridView)

Pergunta
-
Boa tarde!
Estou com uma problemão, e espero que consigam me ajudar!
Vou tentar descrever o cenário, e o problema.
Bom, preciso fazer uma listagem em cascata, ou seja, listo um datagrid, e dentro desse datagrid, listo um gridview.
Acontece, que meu gridview (2° nível), precisa ser montado dinâmicamente, ou seja, montado coluna, por coluna, passado seus fields e todas suas outras propriedades na mão... E dentre essas colunas, eu possuo alguns templates como dropdown e textbox e botões que atualizam linha por linha!
1° Problema: Como persistir os controles?
Por exemplo, coloco um valor no meu textbox, mas na hora de salvar essa linha eu perco o meu controle e consequentemente o valor do controle por causa do postback. O maior problema em persistir esses controles é o fato dele estar dentro de um datagrid, que dificulta o acesso direto.2° Problema: Como alimentar meu combo?
Eu adicionei meu template para o combo, ele aparece perfeitamente, mas como alimenta-lo?Para criar os templates, segue um exemplo abaixo:
public class TemplateColumnDropDown : PaginaBase, System.Web.UI.ITemplate
{
public void InstantiateIn(System.Web.UI.Control container)
{
//adiciona um checkbox na coluna template
System.Web.UI.WebControls.DropDownList ddlParametrizacao = new System.Web.UI.WebControls.DropDownList();
ddlParametrizacao.ID = "ddlParametrizacao";
ddlParametrizacao.DataBinding += new EventHandler(ddlParametrizacao_DataBinding);
container.Controls.Add(ddlParametrizacao);
}
//Evento para mostrar o ltexto no linkbutton
void ddlParametrizacao_DataBinding(object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)sender;
GridViewRow container = (GridViewRow)ddl.NamingContainer;
object cod1 = DataBinder.Eval(container.DataItem, "COD1");
object cod2 = DataBinder.Eval(container.DataItem, "COD2");
if (codPrePedido != DBNull.Value)
{
ddl.DataTextField = "PARAMETRIZACAO1";
ddl.DataValueField = "COD";
string erro = string.Empty;
BIZ BIZ = newBIZ();
IList<TO>List = null;
List = BIZ.Listar(Tratar.Int(cod2), Tratar.Int(cod1));
ddl.DataSource =List;
ddl.DataBind();
}
}
}No código acima, eu crio o template, e em outra parte (não copiei aqui) eu adiciono ele a minha coluna.
E no código acima, também o problema de alimentar o combo, entra em looping infinito.Espero que possam me ajudar.
Aguardo resposta o mais breve possível.
Obrigada.
Simone Trevenzoli
Respostas
-
Segue a solução.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableViewState="false" %> <!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></title> </head> <body> <form id="form1" runat="server"> <div> <asp:DataGrid ID="dgHeader" runat="server" AutoGenerateColumns="False" OnItemDataBound="dgHeader_ItemDataBound"> <Columns> <asp:BoundColumn DataField="CODIGO" HeaderText="Contrato"></asp:BoundColumn> <asp:BoundColumn DataField="Nome" HeaderText="Empresa"></asp:BoundColumn> <asp:TemplateColumn> <ItemTemplate> <asp:GridView runat="server" ID="grvCursos" AutoGenerateColumns="False" onrowcommand="grvCursos_RowCommand" onrowdatabound="grvCursos_RowDataBound"> </asp:GridView> <br /> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid> <br /> <asp:TextBox runat="server" ID="txtSaida" TextMode="MultiLine" Height="106px" Width="277px"></asp:TextBox> </div> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Text; public class Empresa { public int CODIGO { get; set; } public string NOME { get; set; } public static List<Empresa> GetEmpresas() { List<Empresa> lista = new List<Empresa>(); lista.Add(new Empresa() { CODIGO = 1, NOME = "Faculdade Fortium" }); lista.Add(new Empresa() { CODIGO = 2, NOME = "USP - DF" }); lista.Add(new Empresa() { CODIGO = 3, NOME = "Uneb" }); return lista; } } public class Status { public int CODIGO { get; set; } public string DESC { get; set; } public static List<Status> GetStatus() { List<Status> lista = new List<Status>(); lista.Add(new Status() { CODIGO = 1, DESC = "Concluído" }); lista.Add(new Status() { CODIGO = 2, DESC = "Em andamento" }); lista.Add(new Status() { CODIGO = 3, DESC = "Encerrado" }); return lista; } } public class Curso { public int CODIGO { get; set; } public string DESC { get; set; } public static List<Curso> GetCursos() { List<Curso> lista = new List<Curso>(); lista.Add(new Curso() { CODIGO = 1, DESC = "Contabilidade" }); lista.Add(new Curso() { CODIGO = 2, DESC = "Informática" }); lista.Add(new Curso() { CODIGO = 3, DESC = "Letras" }); return lista; } } public class GridViewTemplate : ITemplate { private DataControlRowType templateType; private string columnName; public GridViewTemplate(DataControlRowType type, string colname) { templateType = type; columnName = colname; } public void InstantiateIn(System.Web.UI.Control container) { if (templateType == DataControlRowType.DataRow) { List<Status> status = Status.GetStatus(); DropDownList ddl = new DropDownList(); ddl.ID = "ddlStatus"; ddl.DataTextField = "DESC"; ddl.DataValueField = "CODIGO"; ddl.DataSource = status; ddl.DataBind(); container.Controls.Add(ddl); } } } public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { List<Empresa> empresas = Empresa.GetEmpresas(); dgHeader.DataSource = empresas; dgHeader.DataBind(); } protected void dgHeader_ItemDataBound(object sender, DataGridItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { GridView grv = (GridView)e.Item.FindControl("grvCursos"); BoundField columnCodigo = new BoundField(); columnCodigo.HeaderStyle.HorizontalAlign = HorizontalAlign.Center; columnCodigo.HeaderText = "Codigo"; columnCodigo.DataField = "CODIGO"; grv.Columns.Add(columnCodigo); BoundField columnCurso = new BoundField(); columnCurso.HeaderStyle.HorizontalAlign = HorizontalAlign.Center; columnCurso.HeaderText = "Curso"; columnCurso.DataField = "DESC"; grv.Columns.Add(columnCurso); TemplateField templateEmail = new TemplateField(); templateEmail.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, ""); templateEmail.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, ""); grv.Columns.Add(templateEmail); ButtonField buttonFieldArquivo = new ButtonField(); buttonFieldArquivo.CommandName = "Salvar"; buttonFieldArquivo.Text = "Salvar"; buttonFieldArquivo.ItemStyle.HorizontalAlign = HorizontalAlign.Center; buttonFieldArquivo.ButtonType = ButtonType.Button; grv.Columns.Add(buttonFieldArquivo); List<Curso> cursos = Curso.GetCursos(); grv.DataSource = cursos; grv.DataBind(); } } protected void grvCursos_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { Button btn = (Button)e.Row.Cells[3].Controls[0]; btn.CommandArgument = e.Row.RowIndex.ToString(); } } protected void grvCursos_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName.Equals("Salvar")) { int index = int.Parse(e.CommandArgument.ToString()); // *********** informações do GridView ************* GridView grvCursos = (GridView)sender; //linha selecionada GridViewRow row = grvCursos.Rows[index]; DropDownList ddlStatus = (DropDownList)row.Cells[2].FindControl("ddlStatus"); // *********** informações do DataGrid ************* //Recupera a linha do DataGrid DataGridItem drgRow = (DataGridItem)grvCursos.Parent.Parent; StringBuilder sb = new StringBuilder(); //*********Info DataGrid****************** sb.AppendLine(string.Format("Contrato: {0}", drgRow.Cells[0].Text)); sb.AppendLine(string.Format("Empresa: {0}", drgRow.Cells[1].Text)); //*********Info GridView************ //Codigo do curso sb.AppendLine(string.Format("Codigo: {0}", row.Cells[0].Text)); //Nome do curso sb.AppendLine(string.Format("Nome do curso {0}", row.Cells[1].Text)); //Status do controle DropDownlist sb.AppendLine(string.Format("Status: {0}", ddlStatus.SelectedItem.Text)); //Mostra Itens selecionados no TextBox txtSaida.Text = sb.ToString(); } } }
--
Marque as respostas e ajude a melhorar a busca do fórum.- Marcado como Resposta Simone Trevenzoli segunda-feira, 9 de janeiro de 2012 16:26
Todas as Respostas
-
1: Está tratando o PostBack no page_load para não carregar o grid quando for PostBack?
2: Sobre o "combo", você vai ter que carregar ele no RowDataBound do gridview uma vez que cada linha vai ter um "combo".
--
Marque as respostas e ajude a melhorar a busca do fórum.- Editado Paulo César Viana quinta-feira, 5 de janeiro de 2012 20:21
-
Bom dia, Obrigada Paulo César por responder!!!
Mas o grid que é criado dinamicamente NÃO É CRIADO NO PAGE LOAD...
Ele é criado bound do grid do primeiro nível!
E sobre o combo, o fato dele estar sendo criado dinamicamente, na hr de carregar eu não consigo encontra-lo no rowdatabound.
Obrigada.
Simone Trevenzoli -
-
Na criação do GridView você informa qual é o handler do RowDataBound:
//na criação do grid eu informo o handler do GridViewRowEventHandler gvInteracoes.RowDataBound += new System.Web.UI.WebControls.GridViewRowEventHandler(this.gvInteracoes_RowDataBound); //RowDataBound void gvInteracoes_RowDataBound(Object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { LinkButton visualizar = (LinkButton)e.Row.Cells[2].Controls[0]; visualizar.Enabled = false; visualizar.CommandArgument = e.Row.Cells[3].Text; string arquivo = e.Row.Cells[4].Text.Replace("\"", "").Replace("'", ""); if(arquivo != string.Empty) { visualizar.Enabled = true; } } }
--
Marque as respostas e ajude a melhorar a busca do fórum. -
Simone,
Fiz um exemplo. Veja se ajuda.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public class Status { public int CODIGO { get; set; } public string DESC { get; set; } public static List<Status> GetStatus() { List<Status> lista = new List<Status>(); lista.Add(new Status() { CODIGO = 1, DESC = "Concluído" }); lista.Add(new Status() { CODIGO = 2, DESC = "Em andamento" }); lista.Add(new Status() { CODIGO = 3, DESC = "Encerrado" }); return lista; } } public class Curso { public int CODIGO { get; set; } public string DESC { get; set; } public static List<Curso> GetCursos() { List<Curso> lista = new List<Curso>(); lista.Add(new Curso() { CODIGO = 1, DESC = "Contabilidade" }); lista.Add(new Curso() { CODIGO = 2, DESC = "Informática" }); lista.Add(new Curso() { CODIGO = 3, DESC = "Letras" }); return lista; } } public class GridViewTemplate : ITemplate { private DataControlRowType templateType; private string columnName; public GridViewTemplate(DataControlRowType type, string colname) { templateType = type; columnName = colname; } public void InstantiateIn(System.Web.UI.Control container) { if (templateType == DataControlRowType.DataRow) { List<Status> status = Status.GetStatus(); DropDownList ddl = new DropDownList(); ddl.ID = "ddlStatus"; ddl.DataTextField = "DESC"; ddl.DataValueField = "CODIGO"; ddl.DataSource = status; ddl.DataBind(); container.Controls.Add(ddl); } } } public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void btnCarregar_Click(object sender, EventArgs e) { BindGrid(); } void BindGrid() { GridView grv = new GridView(); grv.AutoGenerateColumns = false; grv.ID = "grvExemplo"; BoundField columnCodigo = new BoundField(); columnCodigo.HeaderStyle.HorizontalAlign = HorizontalAlign.Center; columnCodigo.HeaderText = "Codigo"; columnCodigo.DataField = "CODIGO"; grv.Columns.Add(columnCodigo); BoundField columnMes = new BoundField(); columnMes.HeaderStyle.HorizontalAlign = HorizontalAlign.Center; columnMes.HeaderText = "Curso"; columnMes.DataField = "DESC"; grv.Columns.Add(columnMes); //Status do Curso TemplateField templateEmail = new TemplateField(); templateEmail.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, ""); templateEmail.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, ""); grv.Columns.Add(templateEmail); List<Curso> cursos = Curso.GetCursos(); grv.DataSource = cursos; grv.DataBind(); Panel1.Controls.Add(grv); } }
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!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></title> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="btnCarregar" runat="server" onclick="btnCarregar_Click" Text="Carregar" /> <br /> <asp:Panel ID="Panel1" runat="server"> </asp:Panel> </div> </form> </body> </html>
Referência: http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/Q_23171849.html
--
Marque as respostas e ajude a melhorar a busca do fórum.- Editado Paulo César Viana sexta-feira, 6 de janeiro de 2012 13:57
-
Bom dia Paulo César!
Obrigada pelo exemplo!
Mas, vamos lá, eu fiz exatamente como o seu exemplo, mas agora, vamos super que eu adicionei uma coluna template para um botão, ou um linkbutton, e ao clicar nesses controles, se faz um postback e perco tudo o que eu criei!Eu coloquei a criação do grid no page_load, mas aí ele recria todas colunas.
Entendeu?
Espero que possa me ajudar.
Simone Trevenzoli -
Entendi. É poste este motivo que você precisa validar se é ou não PostBack. Se for não tem que carregar tudo novamente.
Posso colocar um exemplo onde ocorra um PostBack.
protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack) { //faz a carga } }
--
Marque as respostas e ajude a melhorar a busca do fórum. -
-
Não, não funciona! Se eu fizer isso, não carrega o meu grid.
Eu tenho um datagrid, e no itemdatabound dele eu crio meu gridview dinamico. Entendeu qual é o mais problema agora?
Simone Trevenzoli
Entendi faz tempo. Por que um GridView dentro de um DataGrid?? DataGrid que você fala é o DataGridView que era utilizado no 1.1, quando ainda não tinha gridview?
Ok, você diz que perde os dados se ocorrer um postback. Não tem problema. O importante não é ter a linha que foi selecionada? Você pode carregar o gridview novamente e deixar a linha selecionada mesmo com o PostBack.
--
Marque as respostas e ajude a melhorar a busca do fórum. -
É isso mesmo.
Mas acontece que existe uma série de infomações carregadas dinamicamente e que salvo linha por linha. E se eu salvar a linha 10, por exemplo, o restante do grid com os controles dinamicos somem, sendo que eu poderia querer salvar a linha abaixo.
Simone Trevenzoli -
Simone,
Normalmente quando fazemos uma alteração na linha do GridView temos que chamar o método que carrega novamente.
Para que as informações sejam mostradas atualizadas você tem que ter o objeto "atualizado". Seja em sessão, seja vindo do banco de dados. Será que não é isto que falta?
Se você quiser pode entrar em contato em PVT comigo e me passar mais detalhes. Inclusive para que Eu te ajude melhor seria interessante ver o seu código completo.
Uma outra opção é você postar um código que não dependa dos dados vindos do banco de dados. Podemos trabalhar com tudo em memória (alteração, edição, exclusão..)
pcfviana arroba gmail ponto com
--
Marque as respostas e ajude a melhorar a busca do fórum. -
Segue a solução.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableViewState="false" %> <!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></title> </head> <body> <form id="form1" runat="server"> <div> <asp:DataGrid ID="dgHeader" runat="server" AutoGenerateColumns="False" OnItemDataBound="dgHeader_ItemDataBound"> <Columns> <asp:BoundColumn DataField="CODIGO" HeaderText="Contrato"></asp:BoundColumn> <asp:BoundColumn DataField="Nome" HeaderText="Empresa"></asp:BoundColumn> <asp:TemplateColumn> <ItemTemplate> <asp:GridView runat="server" ID="grvCursos" AutoGenerateColumns="False" onrowcommand="grvCursos_RowCommand" onrowdatabound="grvCursos_RowDataBound"> </asp:GridView> <br /> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid> <br /> <asp:TextBox runat="server" ID="txtSaida" TextMode="MultiLine" Height="106px" Width="277px"></asp:TextBox> </div> </form> </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Text; public class Empresa { public int CODIGO { get; set; } public string NOME { get; set; } public static List<Empresa> GetEmpresas() { List<Empresa> lista = new List<Empresa>(); lista.Add(new Empresa() { CODIGO = 1, NOME = "Faculdade Fortium" }); lista.Add(new Empresa() { CODIGO = 2, NOME = "USP - DF" }); lista.Add(new Empresa() { CODIGO = 3, NOME = "Uneb" }); return lista; } } public class Status { public int CODIGO { get; set; } public string DESC { get; set; } public static List<Status> GetStatus() { List<Status> lista = new List<Status>(); lista.Add(new Status() { CODIGO = 1, DESC = "Concluído" }); lista.Add(new Status() { CODIGO = 2, DESC = "Em andamento" }); lista.Add(new Status() { CODIGO = 3, DESC = "Encerrado" }); return lista; } } public class Curso { public int CODIGO { get; set; } public string DESC { get; set; } public static List<Curso> GetCursos() { List<Curso> lista = new List<Curso>(); lista.Add(new Curso() { CODIGO = 1, DESC = "Contabilidade" }); lista.Add(new Curso() { CODIGO = 2, DESC = "Informática" }); lista.Add(new Curso() { CODIGO = 3, DESC = "Letras" }); return lista; } } public class GridViewTemplate : ITemplate { private DataControlRowType templateType; private string columnName; public GridViewTemplate(DataControlRowType type, string colname) { templateType = type; columnName = colname; } public void InstantiateIn(System.Web.UI.Control container) { if (templateType == DataControlRowType.DataRow) { List<Status> status = Status.GetStatus(); DropDownList ddl = new DropDownList(); ddl.ID = "ddlStatus"; ddl.DataTextField = "DESC"; ddl.DataValueField = "CODIGO"; ddl.DataSource = status; ddl.DataBind(); container.Controls.Add(ddl); } } } public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { List<Empresa> empresas = Empresa.GetEmpresas(); dgHeader.DataSource = empresas; dgHeader.DataBind(); } protected void dgHeader_ItemDataBound(object sender, DataGridItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { GridView grv = (GridView)e.Item.FindControl("grvCursos"); BoundField columnCodigo = new BoundField(); columnCodigo.HeaderStyle.HorizontalAlign = HorizontalAlign.Center; columnCodigo.HeaderText = "Codigo"; columnCodigo.DataField = "CODIGO"; grv.Columns.Add(columnCodigo); BoundField columnCurso = new BoundField(); columnCurso.HeaderStyle.HorizontalAlign = HorizontalAlign.Center; columnCurso.HeaderText = "Curso"; columnCurso.DataField = "DESC"; grv.Columns.Add(columnCurso); TemplateField templateEmail = new TemplateField(); templateEmail.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, ""); templateEmail.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, ""); grv.Columns.Add(templateEmail); ButtonField buttonFieldArquivo = new ButtonField(); buttonFieldArquivo.CommandName = "Salvar"; buttonFieldArquivo.Text = "Salvar"; buttonFieldArquivo.ItemStyle.HorizontalAlign = HorizontalAlign.Center; buttonFieldArquivo.ButtonType = ButtonType.Button; grv.Columns.Add(buttonFieldArquivo); List<Curso> cursos = Curso.GetCursos(); grv.DataSource = cursos; grv.DataBind(); } } protected void grvCursos_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { Button btn = (Button)e.Row.Cells[3].Controls[0]; btn.CommandArgument = e.Row.RowIndex.ToString(); } } protected void grvCursos_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName.Equals("Salvar")) { int index = int.Parse(e.CommandArgument.ToString()); // *********** informações do GridView ************* GridView grvCursos = (GridView)sender; //linha selecionada GridViewRow row = grvCursos.Rows[index]; DropDownList ddlStatus = (DropDownList)row.Cells[2].FindControl("ddlStatus"); // *********** informações do DataGrid ************* //Recupera a linha do DataGrid DataGridItem drgRow = (DataGridItem)grvCursos.Parent.Parent; StringBuilder sb = new StringBuilder(); //*********Info DataGrid****************** sb.AppendLine(string.Format("Contrato: {0}", drgRow.Cells[0].Text)); sb.AppendLine(string.Format("Empresa: {0}", drgRow.Cells[1].Text)); //*********Info GridView************ //Codigo do curso sb.AppendLine(string.Format("Codigo: {0}", row.Cells[0].Text)); //Nome do curso sb.AppendLine(string.Format("Nome do curso {0}", row.Cells[1].Text)); //Status do controle DropDownlist sb.AppendLine(string.Format("Status: {0}", ddlStatus.SelectedItem.Text)); //Mostra Itens selecionados no TextBox txtSaida.Text = sb.ToString(); } } }
--
Marque as respostas e ajude a melhorar a busca do fórum.- Marcado como Resposta Simone Trevenzoli segunda-feira, 9 de janeiro de 2012 16:26
-