ASP.Net DropDownList SelectedIndex not changing - asp.net

I am working on a project where I have an OdbcDataReader that reads in the data from a query and populates a DropDownList with the items from the query. When I run the web app and choose different items in the list the selected value never changes whether postback is enabled or not, the smartpaging is enabled, or if the EnableViewState
protected void populateGrid(OdbcDataReader reader)
{
ClientDropDownList.DataSource = reader;
ClientDropDownList.DataTextField = "company";
ClientDropDownList.DataBind();
}

First you should set the AutoPostBack = true for the Dropdownlist control.
Second thing is You should bind the values in the Page_Load event by checking Ispostback
If(! IsPostBack())
{
Bind your dropdownlist here.
}
Thrid thing is As per the Asp.Net Life cycle process.Page load will fire every time.When ever the page getting refresh.

Check that you are not calling PopulateGrid on each PostBack. One of the most common issues people run into.
If your calling PopulateGrid in your Page_Load wrap it in a if (!IsPostBack).

you can use this code:
foreach (ListItem item in YourDropDownList.Items)
{
if (item.Text == defaultText)
{
item.Selected = true;
break;
}
}

Related

Data Bind Asp .Net Drop Down List SelectedValue to Page Property

I have a property in my Page
Public Property Status as String
I set up the status list manually by calling
list.Items.Add(New ListItem("Open", "Open"))
and then I call
list.DataBind()
On my page I want to set the selected value to the value in that property and I want the value in that property to contain the value of the list on each post back.
I tried SelectedValue='<%# Bind("Status") %>' but I get the following error:
Databinding methods such as Eval(), XPath(), and Bind() can only be
used in the context of a data bound control.
Is there something I am missing? The end goal is to have the state of the DropDownList persisted to the Page property between post backs.
Thank you.
You can get the selected value of dropdownlist by
status=DropDownList1.SelectedItem.Value.ToString();
In order to get selected value after each postback,you need to add event in your dropdownlist onselectedindexchanged="DropDownList1_SelectedIndexChanged" and in that event you can get selected value as follows.
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
status=DropDownList1.SelectedItem.Value.ToString();
}
you can persist the value of your status property by creating a view state as follows(in c#)
public string status
{
get
{
if (ViewState["status"] != null)
return ViewState["status"].ToString();
else
return null;
}
set
{
ViewState["status"] = value;
}
}
The server control has viewstate that persist the value of the control between postbacks automatically as long as you don't set the viewstate property of a control to false.
Second thing is you dont need to call it the DataBind() function in your case.

Why does DropDownList.SelectedValue is relied on viewstate?

If I set on my page : EnableViewState="true" ViewStateMode="Disabled" - Then - the Viewstate is disable for the page ( unless override...)
Then, trying to read from (assuming the control has been populated in the last dump to the screen and a value is selected):
MyDDL.SelectedValue will yield ""
That's because of disabled viewstate :
But my question is at a higher level :
If it's all about a form value (which I still can get from Request.Form[MyDDL.UniqueID]) - and we're talking about an input which doesn't need anything to save its value.
Why does the DropDownList property named (SelectedValue) Is relied on ViewState ?
p.s. the TextBox onchangeevent does rely on viewstate although the control is an input (which doesnt need viewstate) - it saves the value of the text and then it compare it when postback.But it only relies on viewstate when you set onchange event ( and autopostback)
The SelectedValue relies on ViewState because on PostBack it rebuilds its ListItems from the ViewState and then sets the selected value on the DropDownList from the Request Object.
It is not taking the Request value as the SelectedValue directly. This in turn is because, ASP.Net can check if the posted DropDownList has not been tampered with at the client. It does so by first de-serializing the original items from the ViewState. It then finds the Request Value in the items and sets its Selected property as true. Only now, the SelectedValue property is available. (or SelectedIndex for that matter). It should be able to fire a SelectedIndexChanged event now.
This is also the reason that you do not need to bind the DropDownList again in PageLoad. The list items are automagically retreived from the ViewState.
If the ViewState is disabled, then there will be no original list items in the ViewState and will be empty. Hence it will not be able to mark any item as selected. Hence the SelectedValue will be 0 or the SelectedItem will be null. I think the SelectedIndexChanged event will also not fire. For things to work in this case databinding needs to be done, preferably on init.
There are workarounds to that however.
Complete Reference: http://msdn.microsoft.com/en-us/library/ms972976.aspx
Edit: (after Op's comments)
Following the page life cycle to see where SelectedValue relies on ViewState:
Stage 1 Init: The control heirarchy is built. If the DropDownList is bound here or the ListItems have been added declaratively, the List gets populated here.
Stage 2 Load ViewState: On PostBack, the ViewState is validated here and loaded into the DropDownList. There is no SelectedValue here.
Stage 3 Load PostBack Data: Here the Request Value (from the form request) is taken and then applied to the control. In this case of DropDownList it now sets the SelectedValue from the received Request Object Value, internal implementation is something like this:
string selectedValue = HttpContext.Current.Request.Form[DropDownList_Id];
Items.FindByValue(selectedValue).Selected = true;
What is important here is that if ViewState is not there and DropDownList is not data-bound, then the ListItem collection will be empty and hence SelectedValue property is 0. This has nothing to do with internal implementation of a property.
If the ViewState is not there (disabled) and DropDownList is data-bound, then the ListItem collection will exist and corresponding item will be marked as selected and hence SelectedValue property will return the correct value.
If the item collection is new (thru a re-binding with different data set or ViewState is invalidated), then the Request Form value would not be found in the item collection and again SelectedValue will be invalid.
Stage 4 Page Load: by this time the ViewState (or data-binding) and PostBack Data has already been loaded.
Stage 5 Raise PostBack Event: At this stage the OnSelectedIndexChanged event of DropDownList is fired if the index was changed in Stage 3.
Hence, the SelectedValue relies on ViewState at Stage 3. Of course, if the control is appropriately data-bound then it will not rely on ViewState as a corollary.
SelectedValue relies on ViewState to make sure the items collection has been populated prior to setting it. Data-binding / Re-binding is just another way to make sure the items collection is populated.
Hope that clarifies.
SUMMARY: If you want the control to work without ViewState, you need to populate/bind the Items collection on every postback. I recommend doing it in the Page_Init event (i.e. OnInit method).
First off, I always recommend this this awesome article: TRULY Understanding ViewState.
The SelectedValue doesn't require ViewState. Looking at the code for ListControl, which DropDownList inherits from, we see the code:
public virtual string SelectedValue
{
get
{
int selectedIndex = this.SelectedIndex;
if (selectedIndex >= 0)
return this.Items[selectedIndex].Value;
else
return string.Empty;
}
The important thing to take away from this code is that the Items list must be populated to get the SelectedValue.
If you utilize ViewState, the Items collection is persisted to / loaded from ViewState, which allows the SelectedValue property to work without rebinding the control.
protected void Page_Load(object sender, EventArgs e)
{
(!Page.IsPostBack)
{
string qry = "SELECT TOP(5)xxx, xxxx FROM dbo.xxxxxx ";
DataSet ds = new DataSet();
ds = SqlHelper.ExecInDS(qry);
drpDwn.DataSource = ds.Tables[0];
drpDwn.DataValueField = Convert.ToString(ds.Tables[0].Columns["xxx"]);
drpDwn.DataTextField = Convert.ToString(ds.Tables[0].Columns["xxx"]);
drpDwn.DataBind();
}
//Here You will get selected value from dropdown
string sss= Request.Form["drpDwn"];
}
If you want the DropDownList to work without ViewState, you can bind the control in page_load only once as given below:
protected void Page_Load(object sender, EventArgs e)
{
//whatever you use declarative binding (in aspx page), or define data source here
if (!IsPostBack)
{
ddl.DataBind(); //fire databinding events and fill items, and selectedvalue has a value.
}
//you can get the selectedvalue
var sv=ddl.SelectedValue ; //
}
In the case ( ViewState is disabled), Asp.net FrameWork retrieve the items from the back end with every PostBack.
In the case (ViewState is enabled), Asp.net FrameWork retrieve the items from the ViewState without hitting the back end with every PostBack
Normally, the Asp.net FrameWork fire the data binding events in PreRender event: Read ASP.NET Page Life Cycle Overview
You can confirm that behavior by enabling Trace.
SelectedValue doesn't rely directly on ViewState from source code of ListControl , BUT depend on items as described above.

Retain textbox values on page refresh

I have a textbox in a user control uc1. I have embedded this uc1 in a page called default.aspx. My issue is after running the application and entering some data in the textbox, when refresh the page i would like to show the values that i have entered in the textbox and not clear the textbox. I would like help with code on how to achive this. Thanks in advance for your help.
Create a global variable at the top of your aspx.cs page:
public string textboxValue
{
get
{
if (ViewState["textboxValue"] != null)
return ViewState["textboxValue"].toString();
else
return "";
}
set
{
ViewState["textboxValue"] = value;
}
}
Then, in PageLoad(), assign textboxValue a value:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
textboxValue = MyTextBox.Value;
else
MyTextBox.Value = textboxValue;
}
You can also use textboxValue to assign the value of MyTextBox at any time, or use it in any other way that might be useful to you.
The default behavior for all asp.net server side controls (runat="server") is to maintain their state. If your textbox is being cleared when your page refreshes, you are likely clearing that value yourself in code.
Are you dynamically adding the textbox or user control? If so, are you doing that during PageInit? Adding them later may cause them to lose state.
I was able to refresh the page without clearing the value in textbox. I did it as below:
I created a public property in the UC1.vb as below:
Public Property textbox_value() As String
Get
If Session("textbox1") IsNot Nothing Then
Return Session("textbox1").ToString()
Else
Return ""
End If
End Get
Set(value As String)
Session("textbox1") = value
End Set
End Property
And in the page_load event of the user control i added the code below:
If IsPostBack Then
textbox_value= textbox1.Text
ElseIf Not IsPostBack Then ' First time the page is loaded or when the page is refreshed
textbox1.Text = textbox_value
End If
Hope it helps.

persist dropdownlist on paging

I have a GridView and I populate it via a List . One of its columns is a DropDownList and AllowPaging is set to true. My problem is when I choose a value on the ddl and after a paging the selected value is lost. Is there any way/idea to persist the selected values?
Thanks for your help.
You could use a Dictionary object within view state to save multiple values i.e.
Dictionary<int, string> ddlValues = new Dictionary<int, string>()
where int is the row index and string is the ddl selected value. Of course this could be an int/guid or whatever depending on the actual value stored in the ddl or an int if you want to work with selectedIndex instead.
on the page event you would need to do
protected void MyGridView_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
for(int rowIndex = 0; rowIndex < myGridView.Rows.Length; rowIndex++)
{
DropdownList ddl = myGridView.Rows[rowIndex].FindControl("ddlId") as DropDownList
if(ddl != null)
{
if(ddl.SelectedIndex > 0) //.. or sensible check appropriate to you
{
int ddlIndex = rowIndex * e.NewPageIndex + 1;
//.. add pageIndex and selectedValue to dictionary
ddlValues.Add(ddlIndex, ddl.SelectedValue);
}
}
}
}
Don't worry about the current page ddl values. These will be persisted with viewstate in the normal way. It is the 'hidden' pages that we are accounting for. Hence we are repopulating the dictionary when the grid pages.
The Dictionary could then be saved in session/viewState and used to rehydrate the dropdownlist by doing the process in reverse. For instance when the page loads (checking !isPostBack) or when the grid rebinds depending on exactly how you have set things up
You will probably want to persist the Data in the ViewState. Check out this MSDN article
http://msdn.microsoft.com/en-us/library/ms972976.aspx
After you save it in the ViewState, you can retrieve the data on PostBack like this:
if (!Page.IsPostBack)
{
//do some stuff
}
else
{
//retrieve the viewstate information
selectedValue= ViewState["dropdownlistValue"].ToString();
}
Alternatively, you could also maintain the information in a Session variable but that may introduce other issues depending on what exactly you are doing.

asp.net : How to check if a dynamically created control has posted back

how to check if a dynamically created control has posted back?The below code is not working.
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button)
{
control = c;
break;
}
if (c is System.Web.UI.WebControls.ImageButton)
{
control = c;
break;
}
}
}
return control;
I have created some imagebuttons dyanmically on page_Init. But the above code always returns null. Why is that? How can I check If an image button has posted back?
Note: I am able to handle the click events of those imagebuttons.
If you want to know which control has initiated the postback at Page_Load time, one Steve C. Orr has some tips:
You can override the
RaisePostBackEvent method of the Page
class. The first parameter sent to
this method is the object that caused
the postback. Remember to call
base.RaisePostBackEvent() so the
postback event gets raised correctly.
Alternately, instead of the load event
you could move your conditional code
to the PreRender event , which happens
after all the control events. So by
then you'll know which control(s)
caused the postback.
...
If your ImageButton is inside a grid,
you can put on your button an
commandName and on itemCommand check
if the command is your command.
http://www.velocityreviews.com/forums/t90304-detect-which-imagebutton-caused-postback.html

Resources