ASP.NET DropDownList SelectedIndex not changing on first element - c#

I used to think my c# programming wasn't too bad, but today I am seriously questioning my head, something so small is defeating me...
I am trying to get a DropDownList to behave but we are not getting on today. I have a simple DropDownList in an ascx control which is dynamically loaded into an aspx page
<asp:DropDownList ID="ddl_SortBy" runat="server" AutoPostBack="true">
<asp:ListItem Value="0">Sort Alphabetically A to Z</asp:ListItem>
<asp:ListItem Value="1">Sort Alphabetically Z to A</asp:ListItem>
</asp:DropDownList>
and some code behind..
private short SortBy = 0;
protected void Page_Load(object sender, EventArgs e)
{
this.ddl_SortBy.SelectedIndex = -1;
this.ddl_SortBy.SelectedIndexChanged += new EventHandler(ddl_SortBy_SelectedIndexChanged);
if (!IsPostBack)
SearchDirectory();
}
public void ddl_SortBy_SelectedIndexChanged(object sender, EventArgs e)
{
SortBy = Convert.ToInt16(this.ddl_SortBy.SelectedItem.Value);
SearchDirectory();
}
I can never get the first item to trigger the selected index change event - as the SearchDirectory() function is not called. I can understand that it's possibly the case that when the control loads the first item IS selected so when selecting, the index isn't actually changing.
I have tried setting the selected item index to -1, and ClearSelection() on page load, but no luck.
Any ideas? Thanks

You are always resetting the SelectedIndex to -1 on every postback:
this.ddl_SortBy.SelectedIndex = -1;
So put that also in the postback-check:
if (!IsPostBack)
{
this.ddl_SortBy.SelectedIndex = -1;
SearchDirectory();
}

I find myself in the same need to execute a change event on Page_Load like you're expecting.. the thing is that I perceived that in ASP.NET before to put some ListItems it set .SelectecIndex to 0.
So if I put some thing like this.ddl_SortBy.SelectedIndex = -1, after that the debugger still shows 0... so it never turn on -1 and never executes the change event. It's like if ASP.NET always considers the first ListItem as the selected one when nothing (-1) is selected, so force it do -1 or 0 never calls change event at the first.
Searching a bit more: "The default value is 0, which selects the first item in the list."
From http://msdn.microsoft.com/en-us/library/vstudio/system.web.ui.webcontrols.dropdownlist.selectedindex(v=vs.100).aspx so I think we must force the call to event like:
ddl_SortBy_SelectedIndexChanged(null, null);

Move the event handler assignment to OnInit from OnLoad and delete the SelectedIndex line.
protected void Page_Init(object sender, EventArgs e)
{
this.ddl_SortBy.SelectedIndexChanged += new EventHandler(ddl_SortBy_SelectedIndexChanged);
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
SearchDirectory();
}

My master page view state was switched off which is why it wasn't working. Though that is not what I want to allow.
My solution was to revert to real form submission data retrieval using Request.Form.
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
SortBy = Convert.ToInt16(Request.Form[this.ddl_SortBy.UniqueID]);
// search directory
SearchDirectory();
}
Works absolutely fine now :)
Thanks everyone.

How about this simple workaround. Set the first item in the drop down to be:
<asp:ListItem Value="-1">(choose how to sort)</asp:ListItem>
That way, the selected index will change and the event will fire when the user selects the desired sort order.
Remove extra fiddling with the drop down from the code behind first.

Related

View State not working correctly Asp.Net c#

I have a gridview that has columns for the days of the week.
I run this code on the fist load of the page so that the dates are correct.
if (!IsPostBack) {//my public function to set the dates, It works as expected.
setUpGrid ();
}
Then I have button that when clicked will show the following week 7 days in the future. That all works as well here is the code
protected void NWeeks_Click (object sender, EventArgs e)
{DateTime hd2 = Convert.ToDateTime (gvappts.Columns [2].HeaderText);
if (ViewState ["hd2"] == null)
{ViewState ["hd2"] = 0;}
ViewState ["hd2"] = ((int)ViewState ["hd2"]) + 7;
gvappts.Columns [2].HeaderText = hd2.AddDays ((int)ViewState["hd2"]).ToString ("ddd dd MMM",
CultureInfo.CreateSpecificCulture ("en-US"));
}
My problem is, you have to click the button twice before it will fire off the next week calculations. I thought the ViewState would take care of this but not sure where I am going wrong.
Thanks In advanced
I realized after looking at this for awhile that since I am dealing with a GridView in order to refresh the HeaderText you also have to DataBind the Gridview. Adding a simple GridviewName.DataBind (); to my function solved my problem.
Thanks for the help!
I imagine you could move your code to the Page_LoadComplete event to ensure all controls are loaded when setUpGrid() is called.
Check out ASP.Net Page Life Cycle
void Page_LoadComplete(object sender, EventArgs e)
{
if (!IsPostBack)
{
setUpGrid ();
}
}

restoring dropdown selected values in c# after refresh by retrieving values from database

I have created a dropdownlist in my webpage which is outside the gridview and I have added automatic refresh. My problem is that I`m unable to retain the selected value in dropdownlist after the refresh. It goes to the default settings in the dropdown. Please help.
Thanks a lot for replying..
part of my code goes this way....
page_load(...)
{
Refresh
if(!IsPostBack)
{
//calling my function which includes databind..
myfunction();
}
}
i tried the same code as you people suggested but its not working..
even now after refresh, the default values appear in dropdownlist
You probably need to implement something like this in your page_load handler:
if (IsPostback) return;
//here populate the dropdown
Let me guess your Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
DataBindGridView(); // loads the datasource of the grid and calls gridView1.DataBind();
DataBindDropDown(); // loads the datasource of the dropdown and calls dropDown1.DataBind();
}
Do not reload all on every postback, just if !(IsPostBack):
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
DataBindGridView();
DataBindDropDown();
}
}
If you need to refresh your GridView don't use Page_Load but the appropriate event handler. If you use an ASP.NET Timer to reload your page periodically to refresh the grid, use it's Tick event.
protected void GridRefreshTimer_Tick(object sender, EventArgs e)
{
DataBindGridView();
}

static bool is always true

I have a web form application that looks like such.
public partial class MyPage : Page
{
private static bool _changed = false;
protected void btnSave_Click(object sender, EventArgs e)
{
if(_changed)
{
//some code here
}
}
protected void btnCancel_Click(object sender, EventArgs e)
{
Response.Redirect("~/MyPage.aspx");
}
protected void dropdownlist_SelectedIndexChanged(object sender, EventArgs e)
{
_changed = true;
}
}
So the gist of what I'm trying to do is that I have a form, which contains a drop down list and a save button. If the user makes a change to the drop down list, I set the private boolean changed to be true. By default, it is false.
For some reason that I do not understand, changed is true when it gets to the btnSave_click method even though it never visited the dropdownlist_selectedIndexChanged method, which is the only place in my code that sets changed to be true.
The markup:
<asp:DropDownList ID="myDropDown" runat=server" OnSelectedIndexChanged="dropdownlist_SelectedIndexChanged" AutoPostBack="true">
<asp:ListItem Value="True">Yes</asp:ListItem>
<asp:ListItem Value="False">No</asp:ListItem>
<asp:Button ID="btnSave" Text="Save" OnClick="btnSave_Click" runat="server" />
Are you really sure that you want to use a static field variable which is shared across all requests? So when UserA selects something in the DropDown, UserB will also have _changed = true.
You might want to use a ViewState or Session variable instead, e.g.:
private bool HasChanged
{
get { object b = ViewState["HasChanged"] ?? false; return (bool)b; }
set { ViewState["HasChanged"] = value; }
}
Nine Options for Managing Persistent User State in Your ASP.NET Application
I think the SelectedIndexChanged gets triggered by the <select> element getting populated with it's initial values. This means that while your form is initializing, before the user can even interact with it, your dropdownlist_SelectedIndexChanged() method is being invoked. You can verify this by using a debugger to see when this method is being executed.
Also, as others have mentioned, a static member is nto a good idea to store request variables; ViewState is better suited for this.
UPDATE
I think the SelectedIndexChanged gets triggered by the <select> element getting populated with it's initial values.
This is not true.
I tested this out with a very simple web-app and the SelectedIndexChanged event does not get fired when initial values are being added to the DropDownList through the declarative file (MyPage.aspx).
I even tried to change the SelectedIndex programmatically in the code behind.
protected void Page_Load(object sender, EventArgs e)
{
myDropDownList.Items.Add(new ListItem("Text", "Value"));
myDropDownList.SelectedIndex = 2;
}
Still, even when doing this, the myDropDownList_SelectedIndexChanged event does not get fired until changing the selected item through interacting with the webpage.

How to find a control inside an asp.net calendar control

After adding a control in the dayrender event, is there a way to find the control later? I have tried
calendar.FindControl("lblSample")
but without success.
Here is some of my code to be more clear:
protected void calSample_DayRender(object sender, DayRenderEventArgs e)
{
Label lblSample = new Label();
lblSample.ID = "lblSample";
lblSample.Text = "Sample";
e.Cell.Controls.Add(lblSample);
}
After the day render event and the page loads completely, I have a link button event where I try and get the control back
protected void lbtnSave_Click(object sender, EventArgs e)
{
//Not working
Label lblSample = calSample.FindControl(lblSample);
//Also can't get to work, this was using Ross' suggestion and the recursive find function he wrote about. I'm probably just not using it correctly.
Label lblSample = ControlFinder.FindControl<Label>(calSample, "lblSample");
}
The issue was because the control was not added to the page until the dayrender method - meaning you could not get a reference to it on a post back. Using the Page.Request.Params collection the OP was able to grab the value out on the postback.
The problem is that the find control is not recursive and the control you want is probably inside another control.
This shows you how to make a recursive find control method that would help: http://stevesmithblog.com/blog/recursive-findcontrol/
Alternatively if you post the calendar controls code I can probably help you a bit more.
Ross
This answer is because of Ross' comment above showing me that I could use the Page.Request.Params to find the value I was after. It's not the cleanest solution but it works!
If you add a dropdownlist to a calendar control in the day render event
protected void calSample_DayRender(object sender, DayRenderEventArgs e)
{
DropDownList ddlSample = new DropDownList();
ddlSample.ID = "ddlSample";
ddlSample.DataSource = sampleDS;
ddlSample.DataBind();
e.Cell.Controls.Add(ddlSample);
}
You can get the selected value back like this, of course I need to put in more checks to verify that the dropdownlist exists, but you get the picture
protected void lbtnSave_Click(object sender, EventArgs e)
{
string sampleID = Page.Request.Params.GetValues("ddlSample")[0];
}

Page lifecycle question

I am using a DropDown menu and an UpdatePanel to filter out a DataGrid. The DataGrid has buttons which redirect to a different page. When I hit the back button or a link on top of the other page, it redirects me to the page with the DropDown as it should...but it gets rid of the DataGrid data and I have to make a selection from the DropDown again. Is there a way to make sure that the DropDown selection is remembered when both the link is pressed and the back button selected? Thanks for your help!
The easiest thing to do in this case is to save the dropdown selection in Session collection
and on page load, check to see if there is a saved selection and use it to reapply the selection.
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Session["SavedSelection"] = DropDownList1.SelectedIndex;
}
protected void Page_Load(object sender, EventArgs e)
{
if(Session["SavedSelection"] != null)
{
int selectedIndex = (int) Session["SavedSelection"];
DropDownList1.SelectedIndex = selectedIndex;
}
}

Categories

Resources