persist ddl values and selected value in between postbacks - c#

I have a save button and a drop down list on a page. Inside the page Load, the drop down list is populated if !Page.PostBack (AutoPostBack=false). So, the first time I load the page, the drop down list is populated. I also have a save method to go with the save button. When this button is clicked, it should do something with the selected value of the drop down list. My problem is that the drop down list has no value (is null) inside the button save method. How would you fix this?
Markup:
MyClass.aspx
<%# Page Language="C#" AutoEventWireup="true" Inherits="MyClass" %>
<asp:Content ID="Content3" ContentPlaceHolderID="MainRegion" runat="server">
<div>
<asp:DropDownList ID="myDdl" runat="server" OnSelectedIndexChanged="myDdlChange" ViewStateMode="Enabled" EnableViewState="true" />
</div>
<br />
<div style="min-width: 300px; max-width: 770px;">
<asp:TextBox id="txtBox" runat="server" TextMode="MultiLine" />
</div>
<div class="buttonContainer">
<span >
<asp:Button ID="btnSave" runat="server" Text="Save" onclick="btnSave_Click" />
</span>
</div>
</asp:Content>
Then, in the code behind:
MyClass.aspx.cs
public class MyClass
{
protected global::System.Web.UI.WebControls.DropDownList myDdl;
protected global::System.Web.UI.WebControls.TextBox txtBox;
protected global::System.Web.UI.WebControls.Button btnSave;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (this.Page.IsPostBack)
Session["selectedID"] = myDdl.SelectedValue; // my attempt to put the selected value from ddl in a session var, to use it later inside the save method but it didn't work
if (!Page.IsPostBack)
{
//create array1 here
myDdl.Items.Clear();
myDdl.Items.AddRange(array1);
Session["selectedID"] = myDdl.SelectedValue;
myDdlChange(null, null);
this.DataBind();
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
//do something based on myDdl.SelectedValue (which shouldn't be null)
}
protected void myDdlChange(object source, EventArgs e)
{
txtBox.Text = myDdl.SelectedValue;
}
}
}

I think the main problem is you should be using Page_Load instead of OnLoad.
You don't need to use Session to remember the SelectedValue.
Try something like this which works for me...
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
PopulateDropdown();
}
private void PopulateDropdown()
{
myDdl.Items.Clear();
var array1 = new ListItem[3];
array1[0] = new ListItem("item1", "item1");
array1[1] = new ListItem("item2", "item2");
array1[2] = new ListItem("item3", "item3");
myDdl.Items.AddRange(array1);
myDdl.DataBind();
}
protected void btnSave_Click(object sender, EventArgs e)
{
var selectedVal = myDdl.SelectedValue; // putting a breakpoint here shows myDdl.SelectedValue is not null
}
protected void myDdlChange(object sender, EventArgs e)
{
}

Related

Checking if the value of a textbox is changed or not

I have a textbox filled at the page load. I want to check the value of the textbox is changed or not in the "update" button press. Any solution? TIA.
Well, you could say use client side javascript.
But, you could also do this:
Say this text box:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:Button ID="Button1" runat="server" Text="Done - continue" OnClick="Button1_Click" />
And our code could be this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// code here to setup and load controls
TextBox1.Text = "Dog";
ViewState["TextBox1"] = "Dog";
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (TextBox1.Text != (string)ViewState["TextBox1"])
{
// then text box was changed
}
}

ASP.NET - SelectedValue/Index in Listbox always changing after a postback

I've been wrestling with this problem for days and so far I haven't been able to find an answer that fits this specific issue. Here's the code to load the list in the PageLoad():
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
lstEmprendimientos.DataSource = Emprendimiento.DevolverEmprendimientosConEvaluacionesIncompletas();
lstEmprendimientos.DataValueField = "id";
lstEmprendimientos.DataTextField = "titulo";
lstEmprendimientos.DataBind();
pnlEvaluador.Visible = false;
}
}
The first method loads a list made up of 'Emprendimiento' objects, and on that list's SelectedIndexChanged I call another method to load a list through a method that uses the SelectedValue of the item selected.
My problem is that, no matter what I do, the SelectedIndex is always reset to 0 after a postback, so I can't load the second list using the SelectedValue properly. I've worked with lists for a long while now and I've never had this problem, so it's really baffling. I'd appreciate some help with this.
Here's the code for the whole page:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
ddlEmprendimientos.DataSource = Emprendimiento.DevolverEmprendimientosConEvaluacionesIncompletas();
ddlEmprendimientos.DataValueField = "id";
ddlEmprendimientos.DataTextField = "titulo";
ddlEmprendimientos.DataBind();
pnlEvaluador.Visible = false;
}
}
protected void lstEmprendimientos_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void lstEvaluadores_SelectedIndexChanged(object sender, EventArgs e)
{
Evaluador ev = Evaluador.FindByID(lstEvaluadores.SelectedValue);
}
protected void btnAsignarEvaluador_Click(object sender, EventArgs e)
{
Emprendimiento emp = Emprendimiento.FindByID(Convert.ToInt32(ddlEmprendimientos.SelectedValue));
Evaluador ev = Evaluador.FindByID(lstEvaluadores.SelectedValue);
Evaluacion eva = new Evaluacion(emp, ev, 0, "justificacion", DateTime.Now, false);
if (eva != null)
{
if (eva.Insertar())
{
lblFeedback.Text = "Alta exitosa.";
emp.listaEvaluaciones.Add(eva);
lstEvaluadores.DataSource = emp.DevolverListaEvaluadoresQueNoEvaluanEmprendimiento();
lstEvaluadores.DataTextField = "Nombre";
lstEvaluadores.DataValueField = "Email";
lstEvaluadores.DataBind();
pnlEvaluador.Visible = true;
CargarEvaluadores();
}
else
{
lblFeedback.Text = "Error en el ingreso de datos.";
}
}
else
{
lblFeedback.Text = "Error en el ingreso de datos.";
}
}
protected void btnSeleccionarEmp_Click(object sender, EventArgs e)
{
CargarEvaluadores();
}
private void CargarEvaluadores()
{
Emprendimiento emp = Emprendimiento.FindByID(Convert.ToInt32(ddlEmprendimientos.SelectedIndex));
lstEvaluadores.DataSource = emp.DevolverListaEvaluadoresQueNoEvaluanEmprendimiento();
lstEvaluadores.DataTextField = "Nombre";
lstEvaluadores.DataValueField = "Email";
lstEvaluadores.DataBind();
pnlEvaluador.Visible = true;
}
protected void ddlEmprendimientos_SelectedIndexChanged(object sender, EventArgs e)
{
CargarEvaluadores();
}
Page markup:
<%Page Title="" Language="C#" MasterPageFile="~/masterPage.Master" AutoEventWireup="true" CodeBehind="asignarEvaluador.aspx.cs" Inherits="InterfazUsuario.asignarEvaluador">
<asp:DropDownList ID="ddlEmprendimientos" runat="server" OnSelectedIndexChanged="ddlEmprendimientos_SelectedIndexChanged">
</asp:DropDownList>
<br />
<br />
<asp:Button ID="btnSeleccionarEmp" runat="server" OnClick="btnSeleccionarEmp_Click" Text="Seleccionar emprendimiento" Width="195px" />
<br />
<br />
<asp:Panel ID="pnlEvaluador" runat="server">
<asp:ListBox ID="lstEvaluadores" runat="server" OnSelectedIndexChanged="lstEvaluadores_SelectedIndexChanged"></asp:ListBox>
<br />
<br />
<asp:Button ID="btnAsignarEvaluador" runat="server" OnClick="btnAsignarEvaluador_Click" Text="Asignar evaluador" Width="135px" />
<br />
<br />
<asp:Label ID="lblFeedback" runat="server"></asp:Label>
<br />
</asp:Panel>
You need to change your DropDownList and ListBox controls to AutoPostback
DropDownList
<asp:DropDownList ID="ddlEmprendimientos" runat="server"
OnSelectedIndexChanged="ddlEmprendimientos_SelectedIndexChanged"
AutoPostBack="True">
</asp:DropDownList>
ListBox
<asp:ListBox ID="lstEvaluadores" runat="server"
OnSelectedIndexChanged="lstEvaluadores_SelectedIndexChanged"
AutoPostBack="True">
</asp:ListBox>
AutoPostBack:
Set this property to true if the server needs to capture the selection
as soon as it is made. For example, other controls on the Web page can
be automatically filled depending on the user's selection from a list
control.
This property can be used to allow automatic population of other controls on > the Web page based on a user's selection from a list.
The value of this property is stored in view state.
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.autopostback(v=vs.110).aspx
I found the problem after checking everything out again.
The DataValueField in the list was 'id', and the id field in the 'Emprendimiento' class wasn't defined, so it was always returning a null int (0). Thank you kindly for the help, it was just a dumb mistake in the end.

How to I carried out Textbox value from ViewState when I postback?

I want to know that how can I trace out the value of Textbox from ViewState.
As user enters any value into Textbox and click submit button because of postback Textbox value disappears ,
But if I used ViewState in this case , then is there any way to see or display that value from Viewstate?
<html>
<body>
<form id="form1" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" /
</form>
</body>
</html>
protected void Button1_Click(object sender, EventArgs e)
{
TextBox1.Text += "X";
}
In your page load use this.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (ViewState["Values"] == null)
{
ViewState["Values"] = new string();
}
}
TextBox1.Text = ViewState["Values"].ToString();
}
After that use this.
protected void Button1_Click(object sender, EventArgs e)
{
ViewState["Values"] += TextBox1.Text;
}
In the first Page_Load method, You will create a ViewState if its not a postback and its null. After that write the textbox your viewstate, in Button1_Click you will add your new textbox1 to your viewstate.

Repeater and Custom Control - Dynamically adding to the collection and retaining values

It has been so long since I've used Web Forms I find myself not remembering most of the perks.
I have a user control that has a button, a repeater and the ItemTemplate property of the repeater is another user control.
<asp:Button runat="server" ID="btnAdd" CssClass="btn" Text="Add" OnClick="btnAdd_Click"/>
<br/>
<asp:Repeater runat="server" ID="rptrRequests">
<ItemTemplate>
<uc1:ucRequest ID="ucNewRequest" runat="server" />
</ItemTemplate>
</asp:Repeater>
The idea is that when the user clicks on the Add button a new instance of the ucRequest is added to the collection. The code behind is as follows:
public partial class ucRequests : UserControl
{
public List<ucRequest> requests
{
get
{
return (from RepeaterItem item in rptrRequests.Items
select (ucRequest) (item.Controls[1])
).ToList();
}
set
{
rptrRequests.DataSource = value;
rptrRequests.DataBind();
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) return;
requests = new List<ucRequest>();
}
protected void btnAdd_Click(object sender, EventArgs e)
{
var reqs = requests;
reqs.Add(new ucRequest());
requests = reqs;
}
}
After much googling I now remember that I should be binding the Repeater in the OnInit method in order for the ViewState to put the captured data of the controls within the ucRequest control on them between post backs but when I try to do that I will always have a single instance of the control on the Repeater since its Items collection is always empty.
How could I manage to do this?
Thanks in advance.
You just need control ids in view state stead of entire control collection.
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="ucRequests.ascx.cs"
Inherits="RepeaterWebApplication.ucRequests" %>
<asp:Button runat="server" ID="btnAdd" CssClass="btn" Text="Add"
OnClick="btnAdd_Click" />
<br /><asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="ucRequest.ascx.cs"
Inherits="RepeaterWebApplication.ucRequest" %>
<asp:TextBox runat="server" ID="TextBox1"></asp:TextBox>
private List<int> _controlIds;
private List<int> ControlIds
{
get
{
if (_controlIds == null)
{
if (ViewState["ControlIds"] != null)
_controlIds = (List<int>) ViewState["ControlIds"];
else
_controlIds = new List<int>();
}
return _controlIds;
}
set { ViewState["ControlIds"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (int id in ControlIds)
{
Control ctrl = Page.LoadControl("ucRequest.ascx");
ctrl.ID = id.ToString();
PlaceHolder1.Controls.Add(ctrl);
}
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
var reqs = ControlIds;
int id = ControlIds.Count + 1;
reqs.Add(id);
ControlIds = reqs;
Control ctrl = Page.LoadControl("ucRequest.ascx");
ctrl.ID = id.ToString();
PlaceHolder1.Controls.Add(ctrl);
}
Try to get the ucRequests during the OnItemDatabound event, at that point you can edit the content of itemtemplate of the repeater. You can get there after the postback caused by the click on the add button. Here's a sample with a similar scenario

What is wrong in this code snippet, writing server side variable on the page as property of asp.net server controls

ASPX Page
<asp:Label ID="lbk" runat="server" Text='<%= _imgPath %>' />
Code behind
protected void Page_Load(object sender, EventArgs e)
{
_imgPath = "MyName";
}
My expectation was that it should render
<span id="lbk">MyName</span>
But it is rendering
<span id="lbk"><%= _imgPath %></span>
Is this correct behavior?
Try this:
<asp:Label ID="lbk" runat="server" Text='<%# _imgPath %>' />
protected void Page_Load(object sender, EventArgs e)
{
lbk.Text = "MyName";
}
you dont need _imgPath.
For something simple like setting the text of a Label, use the Page_Load event in the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lbk.Text = "MyName";
}
}
Of if you'd rather use a script on the page, you can do this:
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lbk.Text = "MyName";
}
}
</script>

Categories