SelectedValue & SelectedItem From Drop Down List - c#

I am attempting to write the selected values to two separate text boxes named this.txtTextSelected.Text = text; and this.txtValueSelected.Text = value;
My issue is that the values are not written to the two text boxes, and when an option is selected my page refreshes and doesn't actually store the selected value which makes me think
1) Either my HTML for the drop down list is incorrect
2) I have added un-needed syntax for something
But I am scratching my head as to what the real deal is.
This is my HTML for the drop down list
<asp:DropDownList ID="dropdownlist1" CssClass="DropDownLists"
runat="server" Width="90px"
AutoPostBack="true"
OnSelectedIndexChanged="dropdownlist1_SelectedIndexChanged">
</asp:DropDownList>
And this is my C# code behind for the page
protected void dropdownlist1_SelectedIndexChanged(object sender, EventArgs e)
{
string value = dropdownlist1.SelectedValue;
string text = dropdownlist1.SelectedItem.Text;
this.txtValueSelected.Text = value;
this.txtTextSelected.Text = text;
}
EDIT
Will this remedy my problem (basing this off #David comment below)
if (!IsPostBack)
{
BindDropDownList();
}

(In response to comments and the question edit...)
Unlike WinForms, WebForms "form" objects don't persist in memory. Web applications are designed to be inherently stateless. So every request results in re-instantiating the targeted form object, which invokes all of the start-up stuff that happens in a form.
This includes Page_Load.
So any time you click a button or do anything that involves posting the page back to the server, Page_Load (and other initialization events) happen again, before any event handlers or custom logic.
This means that if you're binding your controls in Page_Load, you're going to re-bind them before you try to use them. In WebForms, the standard fix for this is to wrap them in a conditional when binding:
if (!IsPostBack)
{
// bind your controls
}
This will bind the controls when initially loading a page, but not when re-submitting the page's form to the page (posting back).

Related

Why is ASP.NET submitting the original value of a TextBox control when the contents have been changed?

I have a web form that allows the user to modify data in certain fields (mostly TextBox controls, with a couple of CheckBox, DropDownList, and one RadioButtonList control) with a submit button to save the changes. Pretty standard stuff. The catch is, I need to keep track of which fields they modified. So I'm using ASP.NET HiddenField controls to store the original value and then on submit comparing that to the value of the corresponding TextBox (for example) control to determine which fields have been modified.
However, when I submit the form and do the comparison, the value of the TextBox control in the code behind still reflects the original value, even though I have changed the contents of the TextBox, so it isn't registering the change. Here is an example of a set of TextBox/HiddenField pairings (in this case last, first, middle names) in my ASP.NET form:
<div id="editName" class="editField" style="display: none">
<asp:TextBox ID="tbxLName" runat="server" class="editable"></asp:TextBox>,
<asp:TextBox ID="tbxFName" runat="server" class="editable"></asp:TextBox>
<asp:TextBox ID="tbxMName" runat="server" class="editable"></asp:TextBox>
<asp:HiddenField ID="hdnLName" runat="server" />
<asp:HiddenField ID="hdnFName" runat="server" />
<asp:HiddenField ID="hdnMName" runat="server" />
</div>
I'm setting the original values of all these controls (".Text" for the TextBox controls, ".Value" for the HiddenField controls) on PageLoad in the code behind.
Here's an example of where I'm doing the comparison when I submit the form (I'm adding the field name, old value, and new value to List<string> objects if the values differ):
if (tbxLName.Text != hdnLName.Value)
{
changes.Add("ConsumerLastName");
oldVal.Add(hdnLName.Value);
newVal.Add(tbxLName.Text);
}
But when I enter a new value into the TextBox control and click Submit:
then step through the code in the debugger, it shows me that the value of the control is still the old value:
Why is the comparison happening against the original value of the TextBox even though the new value is there when I click the submit button?
Update: #David gets the credit for this, even though he didn't post it as an answer -- I was forgetting to enclose the method for pre-filling the original values of the controls in a check for IsPostBack; I really should have known better, I've been doing this for quite a while!
Are you checking for IsPostback in Page_Load so you don't overwrite the values sent in the Postback?
Make sure that you are not overwriting your values in the Page_Load method:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
someTextField = "Some Value";
}
}
It took a while for me to get that the Page_Load method works as an "before anything goes" method and not only a method that is being ran when you visit the page with GET.
Make sure you're not overwriting the value for the textbox somewhere in page init or load without checking for the IsPostback flag.
It may happen due to postback. If you code for set textbox not in !isPostBack then put it.
i.e.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
tbxLName.Text="anything";
}
}

GridView OnRowCommand not fired the first time

This probably looks like a duplicate but I don't think so. I have already searched stackoverflow, may be not enough.
Here is my challenge:
<asp:LinkButton runat="server" ID="DeleteRow" CommandName="deleterow"
CommandArgument='<%# Eval("ID") %>' Text="Delete"
OnClientClick="return confirm('Are you sure you want to delete this record?');" />
If you click the link the first time, OnRowCommand is not fired. When you click it the second time, it works.
I looked at the source and I have these differences.
//When you first load the page: the GUID is the PK for that row
1. javascript:__doPostBack('ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow','')
//After the link was clicked the first time, the link changed and the ID empty, but works
2. javascript:__doPostBack('ctl00$content$gvSchoolClasses$ctl02$DeleteRow','')
I copied the two codes from the href of the asp:LinkButton for BEFORE and AFTER click.
What is wrong? I only have one other event on my page RowDataBound.
protected void gvSchoolClasses_RowDataBound(object sender, GridViewRowEventArgs e)
{
e.Row.ID = Guid.NewGuid().ToString();
}
protected void Page_Load(object sender, EventArgs e)
{
CheckAuthentication();
if (!Page.IsPostBack)
{
ClassesAcademicYearLabel.Text = "- Year " + Setting.Year;
//FillClassesList(); //filling some combo boxes. Have checked the codes here too
//FillLettersList(); //they didn't affect the Grid
FillGrid();
}
ClassErrorLabel.Visible = false;
}
By setting the ID property of the row in the RowDataBound event, you've created the problem you're observing.
Since the RowDataBound event isn't fired until after the page's controls have already been added to the collection, ASP.NET doesn't have a way to update the already-computed client references. Hence, the command doesn't get fired in the way you're expecting.
I've noticed that you're already setting the CommandArgument property to the ID generated in the RowDataBound event, which could also be part of your problem (depends on order of events firing; I don't have a pipeline chart handy).
EDIT: a quick fix for this could be to simply set the ClientID properties (sorry, not the exact name, but intellisense should get you the rest of the way to it) to some sort of Manual, not Auto determination. That way, the ID you set is never changed by the framework.
To elaborate a bit more on why you're seeing this problem, consider the client-side id's presented:
ctl00$content$gvSchoolClasses$ctl02$DeleteRow
This ID is guaranteed to be unique (for this page) by taking the declared ID (DeleteRow) and successively walking UP the control hierarchy and prepending parent ID's to the string. JS code can be confident that passing this string to getElementById will behave in a consistent, predictable manner.
In order to be able to generate said ID, all of the controls in the hierarchy must already be present and accounted for by the rendering engine.
Now let's consider what happens when that the ID property of a control is changed (note this is not the ClientID, but simply the property with a name of ID).
ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow
You'll note that instead of the row's naming container (cl02), it now has the GUID you generated and assigned to it. Client JS attempting to access this container using the previously assigned ID will be disappointed, since it will no longer work as expected!
When an ASP.NET control fires a post-back via a call to javascript:__doPostBack('ctl00$content$gvSchoolClasses$58fd1759-f358-442e-bf73-2e9cedfc27e8$DeleteRow','')
the post-back will occur just fine and dandy, but (and you can verify this by inspecting the form params of the postback) when the server processes the request, it will attempt to rehydrate (from viewstate) a control that doesn't exist. Consequently, it will create a new instance of the control (with the correct ID) which has no idea that a command has been issued, so the XXXCommand event(s) are never fired. Since databinding isn't happening (it's a postback, and your code correctly checks for that condition), the ID is never reset, and the command can be fired normally
don't change the Row.ID in your RowDataBound event. Either change a different value in the grid or just do this in your gridview markup:
CommandArgument='<%: Guid.NewGuid.ToString(); %>'
If you wanted to do it in code behind you could do something like this:
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
LinkButton deleteRow = (LinkButton)e.Row.FindControl("DeleteRow");
if (deleteRow != null)
deleteRow.CommandArgument = Guid.NewGuid().ToString();
}
You need to set the Row Index to the CommandArgument of the Link Button not the guid
As you said it work in the second time but the html is as shown below
//After the link was clicked the first time, the link changed and the ID empty, but works
2. javascript:__doPostBack('ctl00$content$gvSchoolClasses$ctl02$DeleteRow','')

Dynamic data load on ASPX page

I have an internal web service (ASP.NET) written on C# in a company I work for. There are only 2 pages in it, one of this pages contains DropDownList.
Every time when user selecting an item from that DropDownList I need to somehow pass selected item value to a static method and show result string of that method anywhere on page.
I've never worked with ASP.NET or any web programming before and a bit confused about how to do it, not sure where to start looking even.
In your aspx file you should have this:
<asp:ListBox ID="ListBox1" runat="server" AutoPostBack="True"
onselectedindexchanged="ListBox1_SelectedIndexChanged"></asp:ListBox>
Notice the AutoPostBack="True" which goes back to the server and fires the selectedindexchanged event immediately after the user changes the selection in the listbox
In your code-behind (.cs file)
You should have this:
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// Call static method and pass the ListBox1.SelectedIndex
// MyStaticMethod(ListBox1.SelectedIndex);
}
you can either se5t the autoPostBack="true" and handle the change event on the server side or using jQuery subscribe for the change event and get the value on the client side
You should probably check out some of the great resources that microsoft provides for new .NET developers. They will be really helpful in getting you started. Her is a link of some really good videos to help you out: http://www.asp.net/web-forms/videos
Not sure what language you are coming from, if any... But for the most part webforms is going to work a lot like other web based methodologies.
Your ASP.NET Controls (in your case the DropDownList) have both client and server side events.
You will probably want to map the server-side OnSelectedIndexChanged event on your DropDownList.
In order to cause a postback on that control you will want to set the AutoPostBack property to true on your DropDownList.
try this one
In html ,
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True"
onselectedindexchanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
In aspx.cs page,,
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
string selctedValue = DropDownList1.SelectedValue;
/// Call yours static methid here
YourMethod(selctedValue);
}

What is the effect of IsPostBack Condition?

I have a aspx Page where I am using AJAX. like
<asp:UpdatePanel runat="server" ID="upPanelDDLProgram">
<ContentTemplate>
<asp:DropDownList ID="DDLProgram" runat="server" Width="194px" Height="18px" OnSelectedIndexChanged="OnDDLProgramChanged" AutoPostBack="true">
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
and my code behind is like
protected void Page_Load(object sender, EventArgs e)
{
//if (!IsPostBack)
//{
// BindProgramDDL();
//}
BindProgramDDL();
}
protected void BindProgramDDL()
{
List<CcProgramEntity> programEntities = FormSaleSubmit_BAO.GetAllPrograms();
DDLProgram.DataSource = programEntities;
DDLProgram.DataTextField = "Shortname";
DDLProgram.DataValueField = "Id";
DDLProgram.DataBind();
string programCode = programEntities[DDLProgram.SelectedIndex].Code;
}
protected void OnDDLProgramChanged(object sender, EventArgs e)
{
List<CcProgramEntity> programEntities = FormSaleSubmit_BAO.GetAllPrograms();
string programCode = programEntities[DDLProgram.SelectedIndex].Code;
}
the If condition is the page load event, is commented out. If I toggle the comment part of the page load event, it works perfect in both cases. My question is why is this heppening?
IsPostBack tells you if it is a second request to the page. The benefit here is if you need to do anything costly, such as a database call to fill a dropdownlist or similar, you can do it when !IsPostback, then use ViewState to retain the values.
To put it specific to your situation
Using:
if (!IsPostBack)
{
BindProgramDDL();
}
Will result in BindProgramDDL being called ONLY on the first time the page is loaded, all AJAX or other user interaction with the page will NOT call BindProgramDDL;
Without that, in place EVERY page load would call the method, un-necessarily hitting the database for the records.
If I am getting you correct .......
DropDown list has data even you are not binding it second time after post back..........its becasuse its server side control and each serverside control has its view state with it thats y its not removing data.
IsPostBack - it true when do the post back by using serverside control like dropdown, checkbox , textbox............When you load page first time this property is false but in subsequent request to same page value of this property is true. you can check msdn document for more detail about it.
It's basically saying are you visiting the page for the first time (not a post back), or has the user clicked on a control (a post back).
Useful for when you only want to run methods once when the page is initially loaded
You're code should probably look like this to achieve best results
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindProgramDDL();
}
}
I suspect that the DropDownList saves the items in the ViewState and then work with them during all subsequesnt requests. That is why your code works even if the editor's DataSource is set only when IsPostBack returns false.
PostBack event appears on every action (ajax too), except of first page load.
Page.IsPostBack
indicates whether the page is being rendered for the first time or is being loaded in response to a postback.
see http://msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx
Since you've bound your datasource the first time the page was loaded, the data are still in the viewstate and you don't need to update the control (unless the datasource has changed).
Take also into account that, since you're using ajax, you may also want to intercept if there was an 'asynchronous postback'.
See http://encosia.com/are-you-making-these-3-common-aspnet-ajax-mistakes/

Resolving viewstate/namespace conflicts

I have a listbox control. When the user clicks it, it tells a custom control to use a certain ID to use.
The custom control draws the same thing everytime(dynamically), just loads different content depending on this ID(it's loaded from a database into a dynamic form like control).
Ok, Now I'm having trouble with viewstate spillage. When you click the listbox to load say ID #1, it'll all look good. Then, you click on ID #2 and all the textbox controls created inside the custom control has the same thing that was put in ID #1. So when the listbox index changes I need to clear the view state, but I can't get this to work.
All of the controls are created at Page_Load also.
I tried ViewState.Clear() at Page_Load but that didn't do anything.
I had the custom control derive from INamingInterface, but I guess the IDs still match for viewstate.
I've tried changing the custom controls ID to something unique(like "CONROL_"+id.ToString()) I've also tried doing the same thing with the panel containing the custom control.
I can not seem to get rid of this view state!
EDIT
Ok here is code that demonstrates the problem
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (ddl.SelectedValue == "1")
{
Create("ID #1");
}
else if (ddl.SelectedValue == "2")
{
Create("ID #2");
}
}
void Create(string text)
{
TextBox t = new TextBox();
t.Text = text;
pnl.Controls.Add(t);
}
}
the markup:
<div>
<asp:Panel ID="pnl" runat="server">
<asp:DropDownList ID="ddl" runat="server" AutoPostBack="True">
<asp:ListItem Text="id 1" Value="1">
</asp:ListItem>
<asp:ListItem Text="id 2" Value="2"></asp:ListItem>
</asp:DropDownList>
</asp:Panel>
</div>
If you run this code you'll notice that if you change what is in the textbox and then you change the dropdown list, then what you typed earlier will be kept in there instead of it being overwritten..
My basic goal with this is to get it so that when you change to ID #2, it puts "ID #2" in the textbox no matter what(preferably without disabling viewstate altogether)
If I set the ID of the Text control then it doesn't retain the old value. Are you giving all controls a unique id?
void Create(string text)
{
TextBox t = new TextBox();
t.ID = text;
t.Text = text;
pnl.Controls.Add(t);
}
You can't do it that way.
For viewstate to work properly all controls must be created before it is loaded and with the same id's. So you must store the control definitions in session and recreate then with the same ids to ASP.NET load their properties from the view state. Page_load is too late, do it at PreLoad.
But it is easier to have all controls created at design time with visible set to false, and alternate their visibility so viewstate will work properly.
Actually this is no longer relevant. We fixed it by just disabling viewstate for our dynamically created controls. This would not work in all instances, but in our case there are two buttons the user can push(that are to do with the dynamic controls) or a list box to switch forms. The two buttons both save the state of the controls to database, so viewstate is not actually needed.(I always get confused when thinking about viewstate and how it interacts with controls.. )
So basic advice: If your having trouble controlling the viewstate, be sure you actually need it.

Categories