Sharing value from child to parent control - asp.net

I am relatively new to this, but here is my problem.
In asp.net, I have a parent and a child control. Within the child control I have a dropdown list. Based on dropdown list's selected value I would like to toggle Visibility of Panel in parent control. For instance if I select Show in child control dropdown list, I need to pass true to parent control to make Panel visible and vice versa. How should I do that. I have read that can be done via the event handling and have seen certain scenarios but I am not clear on that. Please help!
Thanks.

Raise an event that your parent control listens for.
In the code behind for your parent control, create an object of the type of your child control. Something like:
private MyWebControl childControl;
Then in the child control, define an event
public event System.EventHandler SelectionChanged;
In the OnIndexChanged event of your DropDownList, after you do your processing, raise your event:
if(this.SelectionChanged!= null)
{
this.SelectionChanged(this, new EventArgs());
// You can send the index of the DDL in the event args
}
In your parent control, wire up the event. Page_Init is good
this.childControl.SelectionChanged+=new EventHandler(childControl_SelectionChanged);
Still in the parent control, define your method
private void childControl_SelectionChanged(object sender, EventArgs e)
{
/// Do your processing here.
/// Grab the DDL's index from the EventArgs and do your processing
}
Should be all you need to get it working!

One way to do it is to expose the dropdown list (public) and in your parent control check the child controls dropdown to see if it should show or hide the panel on page load. If this works or not depends a little on the page lifecycle.
Another way to do it is to store the drop-down value in ViewState on the change event. That way the ViewState parameter can be read by the parent control.
If possible you should definitely go for the first option.

Basically, you just need to subscribe to the SelectedIndexChanged event and handle it. The event is fired when the selected item was changed. Note that you should allow auto-postback on the drop down control to make sure the event is fired just after the user changed the drop down's value.
In the ASPX file:
<asp:DropDownList … OnSelectedIndexChanged="OnDropDownChanged">…</asp:dropDownList>
In case you are creating the control in the code-behind, subscribe after creating the control like this:
dropDown.SelectedIndexChanged += OnDropDownChanged;
And then handle it:
public void OnDropDownChanged(object sender, EventArgs e)
{
// alter the panel's visibility here; the drop down's value contains
// the selected item; note that you shoud use "(DropDownList)sender"
// to access it
}
EDIT: Also, have a look on a more elaborate example on MSDN. Note that the event is declared in DropDownList's ancestor 'ListControl'.

Related

Add buttons with css & eventhandlers in Page_Load

Im trying to add buttons to a placeholder, each with an eventhandler to the same method.
if (!this.IsPostBack)
{
foreach (Entry ent in results)
{
HtmlButton btn = new HtmlButton();
btn.ServerClick += new EventHandler(resultSelected);
btn.InnerText = ent.name;
btn.ID = ent.ID.ToString();
PlaceHolder1.Controls.Add(btn);
}
}
1)
The button is added to the page but when its clicked the method (resultSelected) is not called, only Page_Load again. And when it enters Page_Load the PlaceHolder is empty (the button is not displayed on the page). How do I accomplish what Ive tried to do?
2) How do I assign CSS classes to buttons created in this way?
It's quite common issue when you start working with ASP.NET for the first time - adding dynamic controls on server side.
First thing is that You have to add those controls and assign eventhandler on every page request - on every postback as well. For proper event handling and restoring ViewState, you have to assign to them the same IDs and apply the same hierarchy.
Controls needs to be added before Page Load event - most convinient would be adding them on in overriden CreateChildControls() method, which is fired on Postback before OnLoad method.
Events are fired after OnLoaded method, so if you will create any control in for example OnPreRender/Render method - any event won't be fired.
This is most straightforward approach with some details skipped in my description. For more detailed information please read about ASP.NET Application Life Cycle.
As for the second part of your question, you can either use explicit styles setting with Style Property or it should be also possible to add class attribute using Attributes Property, but right now i'm guessing, cause i think HtmlButton doesn't have CssClass property.

ASP.NET drop down selected index not changed event

There is an event onSelectedIndexChange for DropDownList in ASP.NET which triggers when a selected index is changed for a dropdown.
I have encountered a situation where I need to trigger similar kind of event when SelectedIndex of DropDown does not change upon selection.
I am totally puzzled what to do in such a case?
Any help/references will highly be appreciated.
Thank you.
I think that is normal. The event is SelectedIndexChanged and you said you selected the same item that was previously selected before. So the index remains the same, not changed, and the event won't fire. May be you look at OnClick.
The issue is that you have not changed the index when you clicked the second time, so the dropdown is still waiting for you to change it
Assuming you have another server-side control on your page that causes a postback, you could write a routine in the postback event for the other control that compares the current selection with the previous selection and fire a custom-event (or the routines you want to happen) if the value has not changed.
That said, I have to imagine there's an easier way to accomplish the overall goal you're trying to achieve, but you'll have to be a little more specific in your question.
UPDATE
I have to assume that you are using the value from the dropdown when you are processing the form. Why not start off with the dropdown hidden and the linkbutton shown? Just select a default from the dropdown list and allow the user to change it as needed.
Here's a fiddle showing that behavior: http://jsfiddle.net/rjaum/
That's fairly easy.
You can achieve this using javascript/jquery/server side code etc. Assuming user does click the control.
Something like this on pageLoad
PageLoad()
{
YourDropDownList.Attributes.Add("onclick","javascript:CallHelloWorld();return false;");
}
Then on server side you can decorate a method with WebMethod attribute
[WebMethod()]
public static string HelloWorld()
{
return "Hello foo";
}
On your client side aspx you can use jQuery to call your webmethod
<script language="text/javascript">
function CallHelloWorld()
{
// Call HelloWorld webmethod using jQuery $.ajax
}
</script>
Edit
You can use a radiobutton list instead of dropdownlist. That way, on client side you can check the event when the radio button is clicked that it is checked or not (if its checked fire your event).
Edit
Also try looking at this thread if you want to use dropdown list specificallyFire event each time dropdown list is selected with JQuery
assign an a event handler to the selected index changed event and set autopostback to true
in markup
or code behind
mydropdownlist.SelctedIndexChanged += NameOfMethod
the handler is then defined like this
protected void NameOfMethod(object sender, EventArgs e)
{
//your code here
}
update
by definition the selectedindexchanged event would only fire when the index changes. if you want to force the postback that will require some javascript. here is an example of how to do that with jquery
$(function() {
$('select').change();
});

Page Post back initializes the dropdownlist

I face a weird problem. I have a simple aspx page with a dropdownlist. The dropdown gets filled through a function which is called from Page_Load() event. The dropdown item selection triggers event OnSelectedIndexChanged. Now the event triggers rightly
but what happens that upon post back the dropdownlist gets initialized, that is, it shows empty. Never faced this type of issue before so i wonder what's happening wrong.
The piece of code follow:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
PopulateCompanyList(GetCompanies(serverUNCPath));
return;
}
Is ViewState disabled on your dropdownlist, or perhaps the whole application?
The very first ideas:
Check EnableViewState property of
your dropdown and all the parent
controls up to the root (should not be false)
You perform rebinding on postbacks without storing
SelectedValue property
If one of your parent controls is
custom or dynamic it may incorrectly
persist ViewState info (including children).

UserControl events not working for first time

I am calling my user control in a web page dynamically.
For the first time when I click the button on user control, the event is not firing. When I click the same for a second time, the events are firing..
Can anyone help me?
Sounds like the hookup to the button OnClick event is not occurring on every page load, which is required.
Can you guarantee that the hookup is being performed when you add the control and after a poastback to the page? I always put my event hooks in the Page_Init or Page_Load event handlers and outside of any Postback check. Try putting a breakpoint on the Handler hook up and see if the breakpoint gets "hit" twice.
An event hookup for a button would look similar to:
protected void Page_Load(object sender, EventArgs e)
{
btnSearch.Click += new EventHandler(btnSearch_Click); // breakpoint on this line
}
The client id of the control is derived from the ID of all containing controls that are marked with the INamingContainer interface. So, make sure that ALL controls in the hierarchy have a fixed ID.
For example if you have a Button control inside a Repeater, the ID of the button and the repeater are concatenated to make the client ID for the button. So both the repeater and the button should have the same ID across postbacks.
You can compare the HTML for the first request with the HTML of the second request to quickly determine if this is the problem.
Assign an ID for your dynamically created control -- otherwise no events will be fired.
Are you waiting for the download of full page before pressing the button?
The events are javascript functions hidden by ASP.Net in the page, that maybe not present at the time of your clicking.

Creating custom server control to accept user input

I am trying to build a server control that, depending on a "QuestionTypeId" display either a text box, date picker or Yes-No radio buttons.
I have my control displaying how I want it to, but when the submit button is pressed on the form, the text box, date picker or radio buttons that were generated in the RenderContents method are all null.
I have attempted to store the generated controls in view state, that stopped them being null, but the user inputs were not being stored.
I will post code if it is needed. Just ask.
I think you need to create (and add) the controls in CreateChildControls. This will mean you'll need to store the value of the QuestionTypeId in either Viewstate or ControlState (I'd argue that ControlState is applicable in this case, as your control can't work without this value).
When you add controls dynamically, you need to make sure they are recreated before the viewstate is restored.
I haven't done this in a while, but from memory I think you should recreate your controls in the OnInit method. This happens before postback data has been loaded and before the controls have their values set from viewstate.
It may be worth doing some reading on the asp.net page lifecycle:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
You can create a user control and use server controls for textbox, datepicker, radiobuttons.
If you create a cusom server control then you have to add the posted data to your control properties. You can do this at your control OnInit event:
MyProperty = Request.Form("myControl");
A simpler method would be to create all the controls at design time and make the controls invisible based on you requirements.
Example code:
protected void Page_Load(object sender, EventArgs e)
{
txtBox.Visible = QuestionTypeID == 1;
chkBox.Visible = QuestionTypeID == 2;
}
If you do use dynamic controls you should do as David pointed out, save the value QuestionTypeID in ViewState or ControlState and then create the control you want based on that value.
(the control needs to be created every time the page loads even on a post back and they cannot be created later in the page life cycle then the Page_Load method if you want their ViewState persisted and recovered)
Example code:
protected void Page_Load(object sender, EventArgs e)
{
var questionId = ViewState["QuestionTypeID"];
if(questionId == /* Value to create TextBox */) {
var txt = new TextBox { ID = "txt" };
placeHolder.Controls.Add(txt);
} else if(questionId == /* Value to create Calender */) {
var cal = new Calender { ID = "cal" };
placeHolder.Controls.Add(cal);
}
/* Once the controls are added they will be populated with the posted values */
}
P.S.
It's always a good idea with dynamic controls to specify the ID.
You can save the added controls to member variables and use them elsewhere (after they are assigned)
You can subscribe to their events and if the user posted a new value your method will be called
I have followed your advice and done the following:
1) Question Type is stored in view state in my server control.
2) on CreateChildControls now creates a new instance of my control and adds it to a place holder on the page.
My problem now is that things seem to fire in bit of an odd order:
1)On initial load of page, create child controls is fired and the RenderContents method of my server control fires.
2)A button is clicked to load a new contact, this triggers create child controls and RenderContents is fired.
3)details are entered and save is pressed, this triggers Create Child Controls but RenderContents is not triggered and a NullReferenceException is generated by trying to access my control to get the value out. (If i skip the code that access my controls, RenderContents is called and renders.
Seconly, another issue is that when I try an set a value (onDataBind) I try to access the Text box that has been generated in my server control and get another NullReferanceExeption
Thoughts?

Resources