Como posso obter o valor selecionado na lista suspensa no modo de edição de um gridview?
-
12-11-2019 - |
Pergunta
No meu aplicativo, quando edito uma linha no gridview, escolho alguns novos dados em uma lista suspensa.
Estou preenchendo o menu suspenso assim:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
DropDownList emailsListDL = (DropDownList)e.Row.FindControl("emailsDL");
emailsListDL.DataSource = allUsersEmails;//list of strings with the emails of the users
emailsListDL.DataBind();
}
}
}
Mas quando pressiono o botão 'Atualizar' do modelo e entro no evento 'RowUpdating', o valor selecionado na lista suspensa é sempre o primeiro valor dessa lista suspensa.
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
DropDownList emailsListDL = (DropDownList)GridViewAdvertisers.Rows[e.RowIndex].FindControl("emailsDL");
string email = emailsListDL.SelectedValue; //the selected value is every time the first value from the dropdownlist
}
Alguém tem alguma idéia?
Tentei várias maneiras de definir o valor selecionado no evento 'RowDataBound', mas sem sorte.Eu tentei isso:
1. emailsListDL.SelectedIndex = emailsListDL.Items.IndexOf(emailsListDL.Items.FindByValue(DataBinder.Eval(e.Row.DataItem, "OwnerMail").ToString()));
2. emailsListDL.SelectedValue = GridViewAdvertisers.DataKeys[e.Row.RowIndex]["OwnerMail"].ToString();
3. emailsListDL.SelectedValue = GridViewAdvertisers.Rows[e.Row.RowIndex].Cells[1].Text;
//ownerMail is a string (object) from the list of objects that I put as datasource to the gridview
Obrigado, Jeff
Atualizar
Meu modelo de item da página aspx é:
<asp:TemplateField ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Middle"
ItemStyle-Width="150px" HeaderText="Owner Email" HeaderStyle-HorizontalAlign="Left"
HeaderStyle-BorderWidth="1px" HeaderStyle-BorderColor="#e1e1e1">
<ItemTemplate>
<asp:Label ID="LabelEmail" runat="server" Text='<%# Bind("OwnerMail")%>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="emailsDL" runat="server" Width="150">
</asp:DropDownList>
</EditItemTemplate>
<HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Font-Bold="True"></HeaderStyle>
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="180px" BorderWidth="1px"
BorderColor="#e1e1e1"></ItemStyle>
</asp:TemplateField>
Solução
O SelectedIndex sempre será padronizado como 0 se você não o definir em sua definição DropDownList.
Editar:@Tim Schmelter deveria adicionar seu comentário como resposta.Enquanto isso, vou parafrasear para outros leitores:Você precisa verificar o postback (veja os comentários acima).
Outras dicas
Você pode declarar um ComboBox mainBX = new Combobox();
e você pode declarar um evento
private void onSeletedIndexChange(object sender,EventArgs e)
{
mainBX = (ComboBox)(sender);
}
e em seguida você deve iterar foreach ComboBox em GridView e Add this Event .Tudo o que você deve fazer é pegar mainBX.seletedItem();
Acho que é disso que você precisa, se não, peça desculpas.
Para definir o valor selecionado no RowDataBound
-Evento, você deve fazer assim:
(DropDownList)e.Row.Cells[/*index*/].Controls[/*index, or use FindControl*/]).Items.FindByValue(((DataRowView)e.Row.DataItem).Row.ItemArray[/*columnnumber*/].ToString()).Selected = true;
FindByValue encontra o valor de texto atual do campo no modo de visualização "normal" e define DropDownList com o valor.
É claro que isso precisa ser encapsulado em
if ((e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
{
}
Quanto ao seu problema de "obter o valor na atualização", devo dizer honestamente que não tenho ideia, já que sua abordagem é exatamente igual à minha, apenas a diferença:o meu funciona.
Aqui está o meu código, se for de alguma ajuda:
protected void gridVariables_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
string control = ((DropDownList)gridVariables.Rows[e.RowIndex].Cells[3].Controls[1]).SelectedValue;
gridVariables.EditIndex = -1;
this.gridVariables_DataBind(control, e.RowIndex);
}
private void gridVariables_DataBind(string control, int index)
{
DataTable dt = (DataTable)Session["variableTable"]; //features a DataTable with the Contents of the Gridview
dt.Rows[index]["ControlType"] = control;
gridVariables.DataSource = dt;
gridVariables.DataBind();
}
Tive o mesmo problema com uma solução diferente, implementei a paginação customizada no GridView com um pager customizado e, no processo, adicionei o método RowCommand, que estava religando a grade com um novo índice de página.Acontece que o método RowCommand também é chamado durante a atualização.
Então certifique-se de verificar quaisquer outros locais você pode estar vinculando em qualquer lugar do seu código.Espero que isso ajude outra pessoa.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e) { string commandName = e.CommandName; switch (commandName) { case "Page1": HandlePageCommand(e); //binding should happen here break; } //this line is in the wrong location, causing the bug BindGrid1(); }