C# Dynamic created dropdownlist not binding after FormView Update - c#

I am having trouble getting my dropdownlist to populate after I update the sqldatasource or change FormView Modes. The dropdown is created from an array in the code behind. I will post the snips of code below. The dropdown binds as expected until these events.
Any assistance in why this does not work would be awesome.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ID" DataSourceID="tbl_PreRegistration"
Width="100%" CssClass="c2wForm" DefaultMode="Edit">
<EditItemTemplate>
<asp:DropDownList ID="stateDDL" runat="server" OnSelectedIndexChanged="State_DDL_SelectedIndexChanged"
CausesValidation="false" AutoPostBack="true">
</asp:DropDownList>
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update"
Text="Update" CssClass="button blue" />
<asp:LinkButton ID="btnReset" runat="server" CausesValidation="False"
Text="Cancel" CssClass="button white" OnClick="btnReset1_Click" />
</ContentTemplate></asp:UpdatePanel>
</EditItemTemplate>
</asp:FormView>
CODE BEHIND:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
populateStateDDL("stateDDL", "CA");
}
}
protected void populateStateDDL(string DDL_ID, string getCurrentValue)
{
DropDownList strDDL_ID = (DropDownList)FormView1.FindControl(DDL_ID);
ArrayList states = new ArrayList();
strDDL_ID.DataValueField = "Value";
strDDL_ID.DataTextField = "Text";
strDDL_ID.DataSource = formating.GetAllStates();
strDDL_ID.DataBind();
strDDL_ID.SelectedValue = getCurrentValue.ToUpper();
}

you need to create the control every time, not just when postback = false. the control should be rendered in the Init event so that it can then be wired into viewstate and all that other webforms stuff.
here is some pseudo-code
private DropDownList ctrl;
protected override void Init(EventArgs e)
{
base.Init(e);
ctrl = new DropDownList
{
Id = "name of control",
DataValueField = "Value",
DataTextField = "Text"
};
Controls.Add(ctrl);
}
protected override void Load(EventArgs e)
{
base.Load(e);
if(ispostback) return;
ctrl.DataSource = GetData();
DataBind();
}

Related

How can I do a CRUD in this code without database and datatables in webforms gridview, .net core 4.7

Error on RowUpdating >> GridView 'GView' fired the RowUpdating event, which was not handled.
I put the RowEditing and I can enter to update the data, but when I put public void GView_UpdateItem(int id) {} ​​it returns the error saying GridView 'GView' triggered the RowUpdating event, which was not handled.
<asp:GridView runat="server" ID="GView" CellPadding="4" ForeColor="#333333" GridLines="None" OnRowEditing="GView_RowEditing" UpdateMethod="GView_UpdateItem">
<AlternatingRowStyle BackColor="White"></AlternatingRowStyle>
<Columns>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
<asp:CommandField ShowDeleteButton="True"></asp:CommandField>
</Columns>
C# CODE
protected void Page_Load(object sender, EventArgs e)
{
}
public static List<Contato> contatos = new List<Contato>();
public void btnCad(object sender, EventArgs e)
{
Contato contato = new Contato();
contato.Id = contatos.Count;
contato.Nome = this.txtNome.Text;
contato.Idade = this.txtIdade.Text;
contato.Telefone = this.txtTelefone.Text;
contato.Genero = this.txtGenero.Text;
contato.DataCadastro = this.txtDataCad.Text;
contatos.Add(contato);
GView.DataSource = contatos;
GView.DataBind();
}
public void GView_UpdateItem(int id)
{
VoxTraining.Models.Contato item = contatos.Find(cont => cont.Id == id);
if (item == null)
{
ModelState.AddModelError("", String.Format("O item com id {0} não foi encontrado", id));
return;
}
TryUpdateModel(item);
if (ModelState.IsValid)
{
}
}
protected void GView_RowEditing(object sender, GridViewEditEventArgs e)
{
return ;
}
Ok, a few things.
Yes, we can do this without a database. We have have to persist our "list of names".
Dump the delete and edit buttons for the GV - they not worth the trouble - they don't help you.
So, we have the edit area, and the grid.
So, we have this markup:
<div id="myedit" runat="server" style="width:30%;padding:35px;display:none">
<div cssclass="form-group">
<label for="exampleInputEmail1">Nome</label>
<asp:TextBox CssClass="form-control" runat="server" ID="txtNome"></asp:TextBox>
</div>
<div cssclass="form-group">
<label for="exampleInputPassword1">Idade</label>
<asp:TextBox CssClass="form-control" runat="server" ID="txtIdade"></asp:TextBox>
</div>
<div cssclass="form-group">
<label for="exampleInputPassword1">Telefone</label>
<asp:TextBox CssClass="form-control" runat="server" ID="txtTelefone"></asp:TextBox>
</div>
<asp:Label runat="server" AssociatedControlID="txtGenero" ><b>Genero</b></asp:Label><br />
<asp:DropDownList CssClass="form-group" checked="" ID="txtGenero" runat="server" OnSelectedIndexChanged="btnCad">
<asp:ListItem Text="Masculino" />
<asp:ListItem Text="Feminino" />
</asp:DropDownList>
<div cssclass="form-group">
<label for="exampleInputPassword1">Data de Cadastro</label>
<asp:TextBox CssClass="form-control" runat="server" TextMode="Date" ID="txtDataCad"></asp:TextBox>
</div>
<br />
<asp:Button runat="server" ID="IDbtnCad" CssClass="btn" Text="Save" OnClick="btnCad" />
<asp:Button runat="server" ID="btnCancel" CssClass="btn" Text="Cancel" OnClick="btnCancel_Click"
style="margin-left:20px" />
<asp:Button runat="server" ID="btnDelete" CssClass="btn" Text="Delete" OnClick="btnCancel_Click"
style="margin-left:30px" />
</div>
<div id="MyGrid" runat="server">
<asp:Button ID="cmdNew" runat="server" Text="+Add new" CssClass="btn" OnClick="cmdNew_Click"/>
<asp:GridView runat="server" ID="GView" CellPadding="4" ForeColor="#333333" cssclass="table" Width="40%"
ShowHeaderWhenEmpty="true" >
<Columns>
<asp:TemplateField HeaderText="Edit" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn" OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White"></HeaderStyle>
</asp:GridView>
</div>
And code to load is this:
List<Contato> MyNames = new List<Contato>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["MyNames"] = MyNames;
GView.DataSource = MyNames;
GView.DataBind();
}
else
MyNames = ViewState["MyNames"] as List<Contato>;
}
Note how we save the list of names.
So, we now have this:
so, add new button is thus this:
protected void cmdNew_Click(object sender, EventArgs e)
{
// add new
Contato OneName = new Contato();
MyNames.Add(OneName);
MyEdit(MyNames.Count - 1);
}
And my edit is this:
void MyEdit(int RowIndex)
{
Contato OneName = MyNames[RowIndex];
txtNome.Text = OneName.Nome;
txtIdade.Text = OneName.Idade;
txtTelefone.Text = OneName.Telefone;
txtGenero.Text = OneName.Genero;
txtDataCad.Text = OneName.DataCadastro;
ViewState["RowIndex"] = RowIndex;
// show editor, hide grid
myedit.Style.Add("Display", "nomral");
MyGrid.Style.Add("display", "none");
}
so, we hit add, and we now have this:
We hit save button, this code
protected void btnCad(object sender, EventArgs e)
{
int RowIndex = (int)ViewState["RowIndex"];
Contato OneName = MyNames[RowIndex];
OneName.Nome = this.txtNome.Text;
OneName.Idade = this.txtIdade.Text;
OneName.Telefone = this.txtTelefone.Text;
OneName.Genero = this.txtGenero.Text;
OneName.DataCadastro = txtDataCad.Text;
ViewState["MyNames"] = MyNames;
myedit.Style.Add("Display", "none");
MyGrid.Style.Add("display", "normal");
GView.DataSource = MyNames;
GView.DataBind();
}
And we now have this:
We can use add again, and now this:
the edit row button - plane jane asp.net button click.
Code is this:
protected void cmdEdit_Click(object sender, EventArgs e)
{
Button btnEdit = sender as Button;
GridViewRow gRow = btnEdit.NamingContainer as GridViewRow;
MyEdit(gRow.RowIndex);
}
So, hitting edit button, goes back to the editor.
Say like this:
Cancel button - does nothing (no save, return to grid).
Say this:
protected void btnCancel_Click(object sender, EventArgs e)
{
myedit.Style.Add("Display", "none");
MyGrid.Style.Add("display", "normal");
}
And the delete button - that would just remove the current row index item from the list.
eg:
protected void cmdDel_Click(object sender, EventArgs e)
{
myedit.Style.Add("Display", "none");
MyGrid.Style.Add("display", "normal");
int RowIndex = (int)ViewState["RowIndex"];
MyNames.RemoveAt(RowIndex);
GView.DataSource = MyNames;
GView.DataBind();
}

ASP.NET Get value from DropDownList in EditItemTemplate in codebehind

I have a GridView that I have placed in DropDownList's in 2 columns.
<asp:TemplateField HeaderText="Upgrade" SortExpression="Upgrade">
<ItemTemplate>
<asp:Label ID="LabelUpgrade" runat="server" Text='<%# Eval("Upgrade") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlUpgrade" runat="server" Width="100px">
<asp:ListItem Value="1">--Select--</asp:ListItem>
<asp:ListItem Value="2">1</asp:ListItem>
<asp:ListItem Value="3">2</asp:ListItem>
<asp:ListItem Value="4">3</asp:ListItem>
<asp:ListItem Value="5">4</asp:ListItem>
<asp:ListItem Value="6">5</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
how do I grab the item from ddlUpgrade in the codebehind?
OnUpdating Event - I don't have a way to pull the row to get the value from the drop down but I add my sql parameters here.
protected void IAP_Updating(object sender, SqlDataSourceCommandEventArgs e){}
RowUpdating Event - I can get the row here but I can't add the value to the sql parameters because e.command isn't valid here
protected void gvClients_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow _row = gvClients.Rows[e.RowIndex];
DropDownList _ddl = (DropDownList)_row.FindControl("ddlUpgrade");
SqlParameter _parm = new SqlParameter("#Upgrade", _ddl.SelectedItem.ToString());
}
On the RowUpdating event you can capture the control inside the edit template based on its ID.
GridViewRow row = GridView1.Rows[e.RowIndex];
DropDownList ddl = (DropDownList)row.FindControl("ddlUpgrade");
SqlParameter _parm = new SqlParameter("#Upgrade", ddl.SelectedItem.ToString());
e.Command.Parameters.Add(_parm);
I would add a hidden field outside the GridView:
<asp:HiddenField ID="hdnSelection" value="" runat="server" />
And change the gvClients_RowUpdating method:
protected void gvClients_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow _row = gvClients.Rows[e.RowIndex];
DropDownList _ddl = _row.FindControl("ddlUpgrade") as DropDownList;
if(_ddl != null)
{
hdnSelection.Value = _ddl.SelectedItem.Text;
IAP.Update();//Assuming IAP is the ID of the SqlDataSource
}
}
And my IAP_Updating method should look like this:
protected void IAP_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
SqlParameter _parm = new SqlParameter("#Upgrade", hdnSelection.Value);
e.Command.Parameters.Add(_parm);
}
I did not test the code. You may need to tweak.

How to access control inside parent control? (asp.net c#)

I have page with listview in it. There is label and dropdownlist in listview. I would like to access the text of label from ddlTags_Init() method.
Code:
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1"
DataKeyNames="id_Image" onitemdatabound="ListView1_ItemDataBound">
<ItemTemplate>
<asp:Label ID="TagsLabel" runat="server" Text='<%# Eval("Tags") %>' />
<asp:DropDownList ID="ddlTags" runat="server" OnInit="ddlTags_Init" >
</asp:DropDownList>
</ItemTemplate>
</asp:ListView>
Code behind:
protected void ddlTags_Init(object sender, EventArgs e)
{
DropDownList ddlTags = (DropDownList)sender;
Label lblTag = (Label)ddlTags.Parent.FindControl("TagsLabel");
string text=lblTag.Text;
}
At the moment i am stuck with
Label lblTag = (Label)ddlTags.Parent.FindControl("TagsLabel");
Anyone knows what am i missing?
Thanks, Jim
Assuming that there are more than 1 elements in the listview datasource, why don't you put your code in the ItemDataBound handler? I think that it should work.
Init is too early to get the bind value of Label. In other words, label value hasn't been bind yet.
Instead you might want to consider using ItemDataBound method.
<asp:ListView ID="ListView1" runat="server"
OnItemDataBound="ListView1_ItemDataBound" ...>
....
</asp:ListView>
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var ddlTags = e.Item.FindControl("ddlTags") as DropDownList;
var tagsLabel = e.Item.FindControl("TagsLabel") as Label;
}
}

Gridview click on row enable controls

I have a gridview. The gridview has a textbox multiline that keeps an text. After that I have a column with imagebutton named approved, and one named not approved. I want to force the user before click approved or not approved to read the text inside the multiline box. How can I achieve this programmatically? I know I should create a Rowdatabound Event, but what I should do with the code? I am using c# ASP.NET web application.
I know you can track the scroll bar of the browser using javascript but I've personally never come across similar functionality for a text box. I would suggest trying a slightly different approach, why don't you add an extra column to you grid view which has a check box control for - I've read and accepted the agreement. And the Approve button will only be enabledd when the checkbox is checked, here's an example:
ASPX:
<div>
<asp:ScriptManager ID="sm" runat="server" />
<asp:UpdatePanel ID="updatePanel" runat="server">
<ContentTemplate>
<asp:GridView ID="grid" runat="server" AutoGenerateColumns="false" OnRowDataBound="grid_RowDataBound">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox TextMode="MultiLine" runat="server" ID="txtAgreement" Text='<%# Eval("Agreement") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
I have read and accepted the agreement
<asp:CheckBox ID="chkAgreement" AutoPostBack="true" runat="server" OnCheckedChanged="CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnAccept" runat="server" Text="Accept" OnClick="Accept" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
Code behind:
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var items = new List<License> { new License { Agreement = "Agreement 1" }, new License { Agreement = "Agreement 2" } };
grid.DataSource = items;
grid.DataBind();
}
}
protected void Accept(object sender, EventArgs e)
{
}
protected void grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
(e.Row.FindControl("btnAccept") as Button).Enabled = false;
}
protected void CheckedChanged(object sender, EventArgs e)
{
var chkAgreement = sender as CheckBox;
Button btnAccept = null;
if (chkAgreement != null)
{
var row = chkAgreement.Parent.Parent as GridViewRow;
btnAccept = row.FindControl("btnAccept") as Button;
if (btnAccept != null)
if (chkAgreement.Checked)
btnAccept.Enabled = true;
else
btnAccept.Enabled = false;
}
}
}
public class License
{
public string Agreement { get; set; }
}

Rebinding on Postback Based on Selected DropDown Value

Greetings!
I have a DropDownList within a FormView which are bound to XmlDataSources:
<asp:FormView ID="MyFormView" runat="server" DataSourceID="MyXmlDataSource">
<ItemTemplate>
<h1><%# XPath("SomeNode")%></h1>
<asp:Label ID="MyLabel" runat="server" AssociatedControlID="MyDdl" Text='<%# XPath("SomeOtherNode")%>' />
<asp:DropDownList ID="MyDdl"
runat="server"
DataSourceID="MyDdlDataSource"
DataTextField="name"
DataValueField="value"
AutoPostBack="true"
OnSelectedIndexChanged="MyDdl_SelectedIndexChanged">
</asp:DropDownList>
</ItemTemplate>
</asp:FormView>
<asp:XmlDataSource ID="MyXmlDataSource" runat="server" XPath="Root/MainSection" />
<asp:XmlDataSource ID="MyDdlDataSource" runat="server" XPath="Root/MainSection/Areas/*" />
In the page's codebehind, I have the following OnLoad() method as well as the method for when the select index of the dropdownlist changes:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
string xml = GetMyXml(0); // default value
MyXmlDataSource.Data = xml;
MyDdlDataSource.Data = xml;
}
}
protected void MyDdl_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList l_MyDdl = FindControl("MyDdl") as DropDownList;
int myVal;
if (l_MyDdl != null)
if (!Int32.TryParse(l_MyDdl.SelectedItem.Value, out myVal))
myVal = 0;
string xml = GetMyXml(myVal);
MyXmlDataSource.Data = xml;
MyDdlDataSource.Data = xml;
}
When a different value is selected from the dropdown list and SelectedIndexChanged is invoked, I am unable to get the value of the dropdown list (FindControl always returns null) in order to use it to re-bind the datasources. How can I get this value?
Because your dropdownlist is contained within another control it may be that you need a recursive findcontrol.
http://weblogs.asp.net/palermo4/archive/2007/04/13/recursive-findcontrol-t.aspx

Categories