Selected Item not being updated? - c#

I've got the following DropDownList control:
<asp:DropDownList ID="SubjectFilter" runat="server" AutoPostBack="True" onselectedindexchanged="SubjectFilter_SelectedIndexChanged"></asp:DropDownList>
SubjectFilter data:
BookStore b = new BookStore();
b.LoadFromXML(Server.MapPath("list.xml"));
SubjectFilter.DataSource = b.BooksList.Select(x => x.Subject).Distinct().ToArray();
SubjectFilter.DataBind();
SubjectFilter.Items.Insert(0, new ListItem("הכל", "Default"));
Everything loads just fine. However in the SubjectFilter_SelectedIndexChanged method, SubjectFilter.SelectedValue is always Default, even though I'm selecting different options.
What is the problem?
Thank you very much.

I'm guessing the above code is from the PageLoad event. You may want to wrap that in a if(!isPostBack) block.

Make sure that in your Page_Load that you only populate the dropdown when IsPostBack is false.
For example
public void Page_Load(...)
{
if (!IsPostback())
UpdateDisplay();
}

When are you binding the drop down? You may any to wrap in an
If(page.ispostback ==false)
It looks like you may be binding on page load, before you check its value..

ViewState is assigned between the Init and Load for an ASP.NET page. Your event handlers occur after load. If you are programmatically setting content in the controls that your user will be using, you want to handle that before ViewState is applied. In other words, move it to Page_Init. Afterwards, ViewState kicks in and you'll see what the user actually selected when your handler executes.

Related

DropDownList events don't fire

I’m having trouble with my DropDownList. The events don’t fire! I've tested it on a separate project, with a DropDownList and a literal. Every time the selected value would change, I would add a little star “*” to the literal. No problems what so ever. But every time I try it on my webpage in the project, it fails.
Here is an image.
protected void ddlConsole_SelectedIndexChanged(object sender, EventArgs e)
{
ltlTesting.Text += "*";
}
UPDATE:
I've tried some things but still with no succes. I hope someone can tell me what i'm doing wrong. I'm wiring the events in the code behind now, but i've added a linkbutton next to the dropdownlist to see if it works.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
ddlConsole.SelectedIndexChanged += new EventHandler(ddlConsole_SelectedIndexChanged);
lnkGet.Click += new EventHandler(ddlConsole_SelectedIndexChanged);
}
Here is an image to see what's going on. The stripe in the literal at the beginning is added in pageload with the same code the star is added. Just to be sure it doesn't load twice. The "GET" linkbutton works fine. The dropdownlist doesn't...
Have you Set
AutoPostBack="true"
in control properties??
EDIT:
Remove
OnSelectedIndexChanged="ddlConsole_SelectedIndexChanged"
from the markup in the ASPX page and try again only with AutoPostback true and the
event defined in codebehind. The aspx page should look like this:
<asp:DropDownList runat="server" ID="ddlConsole" AutoPostBack="True"></asp:DropDownList>
Is the AutoPostBack of the dropdownlist true ?
Check AutopostBack property of Dropdownlist set it to true :
If picture is right and the AutoPostBack="True", is there any code that sets the value of ltlTesting when page loads?
Add the AutoPostback="True" and OnSelectedIndexChanged="ddlConsole_SelectedIndexChanged" to the ddlConsole attributes. You can delete the OnInit method, since you bound the SeletedIndexChanged event at design time.

Asp.net Hidden field not having value in code behind, but *is* retaining value after postbacks

In my ASCX, I have an asp.net hidden field defined as <asp:HiddenField ID="hdnNewAsset" runat="server" />.
In the Code Behind I have the following code:
protected void Page_Load(object sender, EventArgs e)
{
_service = new ArticleDataService(PortalId);
if (!IsPostBack)
{
string rawId = Request[ArticleQueryParams.ArticleId];
DisplayArticleDetails(rawId);
}
if (hdnNewAsset.Value.Trim() != string.Empty)
ProcessNewAsset();
}
Now, in my frontend, I have a javascript function to react to an event and set the hidden field and trigger a postback:
function assetSelected(assetGuid) {
$('input[id*="hdnNewAsset"]').val(assetGuid);
__doPostBack()
}
What's happening is that my hidden field is being set in the markup (chrome shows [
<input type=​"hidden" name=​"dnn$ctr466$Main$ctl00$hdnNewAsset" id=​"dnn_ctr466_Main_ctl00_hdnNewAsset" value=​"98d88e72-088c-40a4-9022-565a53dc33c4">​
] for $('input[id*="hdnNewAsset"]')).
However, when the postback occurs, hdnNewAsset.Value is an empty string.
What's even more puzzling is that at the beginning of Page_Load Request.Params["dnn$ctr466$Main$ctl00$hdnNewAsset"] shows 98d88e72-088c-40a4-9022-565a53dc33c4, and after the postback my hidden field has the same value (so the hidden field is persisting across postbacks), yet I cannot access this value via hdnNewAsset.Value.
Can anyone see what I"m doing wrong?
Ok I figured out the the issue.
The issue is that the code posted above was part of an ASCX user control. That user control was being loaded dynamically into an asp.net placeholder during the Page_Load event of the parent control.
Therefore, it seems that since both of these calls were in Page_Load of their respective calls, the inner control did not have it's values bound in the inner control's page_load. Modifying it so my inner control is loaded in Page_Init instead of Page_Load fixed all bindings.
Not sure if I wrote that in a way that makes sense to the general public.
Edit: It seems this part of the MSDN documentation is relevant to my issue:
If controls are created dynamically at run time or declaratively within templates of data-bound controls, their events are initially not synchronized with those of other controls on the page. For example, for a control that is added at run time, the Init and Load events might occur much later in the page life cycle than the same events for controls created declaratively. Therefore, from the time that they are instantiated, dynamically added controls and controls in templates raise their events one after the other until they have caught up to the event during which it was added to the Controls collection.

Dynamically adding a command button to a GridView

I'm having an issue with trying to add a button to my grid. My GridView is first loaded with data in the PageLoad event.
I'm then taking the data in the first cell of each row, and creating a button that will link to a URL. To get the URL, I have to run a query with the data in the first cell as a parameter. I was doing this in the RowDataBound event at first, but hitting that query for every row was making it really slow.
So I decided to add a button that would retrieve the URL only when you clicked the button.
Here's my GridView:
<asp:GridView ID="gvResults" runat="server"
OnRowDataBound="gvResults_RowDataBound"
OnRowCommand="gvResults_RowCommand">
</asp:GridView>
And my code:
protected void gvResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.DataItem != null)
{
LinkButton lb = new LinkButton();
lb.CommandArgument = e.Row.Cells[0].Text;
lb.CommandName = "NumClick";
lb.Text = e.Row.Cells[0].Text;
e.Row.Cells[0].Controls.Add((Control)lb);
}
}
protected void gvResults_RowCommand(object sender, CommandEventArgs e)
{
switch (e.CommandName.ToLower())
{
case "numclick":
string url = GetUrl(e.CommandArgument.ToString());
Response.Redirect(url);
break;
default:
break;
}
}
The grid generates fine, the button gets added to the grid for each row. But when I click on it, the RowCommand event doesn't fire, and the page just refreshes.
Does anyone know what the issue is?
Why use a dynamic button at all? You can easily put the linkbutton directly into the markup of the gridview (as long as you don't mind using a template field) and there will be no need to mess around with the RowDataBound event.
Your markup would look something like the following:
<Columns>
<asp:TemplateField HeaderText="SomeHeaderText">
<ItemTemplate>
<asp:LinkButton ID="lnkBtn" runat="server" CommandName="NumClick" CommandArgument= '<%# (string)Eval("dbValue") %>' Text='<%# (string)Eval("dbValue") %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField></asp:BoundField>
<asp:BoundField></asp:BoundField>
<asp:BoundField></asp:BoundField>
</Columns>
Add breakpoints to the RowCommand event and make sure that you can hit the breakpoints.
The problem may lie elsewhere.
Also, make sure that you're not databinding on postback.
You have a big trouble with your code. It's pretty hard for me to explain what's your big mistake, but I can easily tell you how to fix.
The problem is that you generate a new button inside the RowDataBound event, definitely the wrongest choice. The button gets rendered because it exists after that event when page renders, but doesn't exist before data binding. If you bind data everytime you load the page (even during postback) the button still gets rendered because you generate a new button.
But since the button doesn't exist before data binding, it cannot raise events. You must declare the button from markup into a template of GridView, then access it not by using new LinkButton() but by using e.Row.Cells[0].FindControl("buttonId") and set its text. Then, you have to set its markup in order to fire its own Command event (not RowCommand) and handle it as you used (don't forget to set CommandArgument during data binding)
[Edit] I also made a mistake: controls inside data bound controls also don't exist before data binding. But they are initialized not with new Control() (by the private methods of data bound control) but with Page.LoadControl(typeof(Control)). That's the first thing you must fix when you load controls dynamically!!
Because the control is added dynamically on databind and you have to databind the gridview for each postback, the control being "clicked" is different each time. The event doesn't fire because at the time it needs to fire it doesn't exist as it did in the last iteration of the page.
I notice you don't have any logic determine if the button should be there, and it always goes into cell[0].
You should place this button into a TemplateItem so that it exists properly. If you have a need to do it in code-behind, you are probably better served doing it in the RowCreated event.

Iterating Dynamic FileUpload Control Collection in Panel Control using ASP.NET C#

I'm trying to get the values of dynamically generated FileUpload controls that I add to a Panel:
<asp:Panel ID="pFileControls" runat="server">
</asp:Panel>
I create the controls during a loop through a record set:
foreach(DataRow dr in ds.Tables[0].Rows)
{
FileUpload fu = new FileUpload();
fu.ID = dr["SomeID"].ToString();
pFileControls.Controls.Add(fu);
}
Everything works fine up to the point where I submit the form with this button:
<asp:Button ID="btnImportFile" runat="server" Text="Save" OnClick="btnImportFile_Click" />
Which I register like this (Page_Load):
ScriptManager.GetCurrent(this).RegisterPostBackControl(btnImportFile);
I do this because I'm using a MasterPage/ContentPage setting in my website and mostly everything happens inside an UpdatePanel for AJAXification purposes. Bear in mind that if I explicity specify a FileUpload Control in the HTML view, it works 100%.
When the form is submitted I try to iterate the Panel like this:
foreach (Control ctrl in pFileControls.Controls)
{
if (ctrl.GetType() != typeof(FileUpload))
{
continue;
}
//Do the saving of the file here
}
Except, the Panel seems to only return one control: The Content Place Holder for the page and nothing else. Does anyone have some ideas about this?
What part of the life cycle are you adding the dynamic controls?
if you are putting them in the page_load it may be too late, try putting the generation of the dynamic controls into the page_init and see if that fixes the problem.
page lifecycle
http://msdn.microsoft.com/en-us/library/ms178472.aspx
dynamic controls
http://geekswithblogs.net/shahed/archive/2008/06/26/123391.aspx
Note:
"Its recommended to load the dynamic
controls during the Page_Init instead,
because we may want to hook up our
events with proper handler at an early
stage. ... Do not assigning
properties of a dynamic control
(viewstate enabled), during Page_Init,
it will not be reflected. "
I would expect that even with the update panel, you will need to be mindful of the page_load limitations with dynamic controls.
let me know if this helps or if I missed the mark!
Let's try a different course of action (I've gotten dynamic file upload to work, but it was a bear and I wish I had simply used this)
http://www.asp.net/ajaxlibrary/act_AsyncFileUpload.ashx
or
http://en.fileuploadajax.subgurim.net/
these may not create a 'loop' of elements, but you can simply keep loading docs on a as-needed basis.
I have specifically used
http://www.asp.net/ajaxlibrary/act_AsyncFileUpload.ashx
to great effect.
There also appear to be some limitations to the update:panel and the file upload, check out these sites.
(this one says it does not work in partial update status but does work in full postback)
http://forums.asp.net/p/1105208/1689084.aspx
do you know if the submit is triggering the full page or just the update:panel? (check out this: http://geekswithblogs.net/mmintoff/archive/2009/04/01/fileupload-within-updatepanel.aspx

FindControl doesn't work with bind server tag, why?

I have a FindControl in OnLoad event to find my button on page i.e.:
protected override void OnLoad(EventArgs e)
{
DataBind();
control button = Page.FindControl("myButton");
}
on my aspx page I have
<asp:Button runat="server" ID="myButton" />
If I only have this, everything works, when I pass in the OnLoad, button is not null and I can execute what I want. The problem is when I add dynamic text in my aspx:
<asp:Button runat="server" ID="myButton" Text='<%# "Here is my dynamic text pulled from a XML" %>' />
Then the FindControl finds nothing and the button is null.
Adding a binding server tag on aspx isn't suppose to delay anything right? When I inspect the Page object I have some controls in Controls collection, but I'm unable to find myButton.
Any idea on what I am doing wrong?
EDIT
People seem to think that my code example is my real code but it isn't, So I use FindControl because I need to since I have nested controls and I cannot access it directly and I use binding because the dynamic text I'm putting is inside a ContentTemplate which I can override in other page aspx.
The question I asked was more specific to the fact that I have traced the problem where my FindControl returns null because a newly implement behaviour which is the binding.
Improving the code example isn't a solution or an explanation to the fact that if I put a <%# %> tag in my aspx page, the FindControl in the OnLoad event return null.
EDIT 2
the bind tag alone seems to not be the culprit but the DataBind() to populate them. Whether or not I have bind tag, putting DataBind() before the FindControl makes the myButton to be null. Correction in code example was made.
In here MSDN says that :
PreRender : Each data bound control whose
DataSourceID property is set calls its
DataBind method.
It looks like you're not using DataSourceID of your data bound control, but moving your FindControl code to PreRender event might help.
The Page.FindControl() method will only search the imediate collection of controls that are associated with Page. It will not recurse down the entire control tree, so if your button is contained within another control it will not be found. You would need to call the FindControl method on the containing control.
If you want to access a button on your page, you can directly refer to the button as -
this.myButton
And as far as assigning values is concerned, you can do it like this in your server code -
this.myButton.Text = "Dynamic Text";
<%# xyz %> is only used when you are databinding the controls, for e.g. in a DataGrid, GridView, etc.
In your override dont you want to call base.OnLoad(e) in your method first ?

Categories

Resources