Event wont fire in custom control - c#

I am trying to create a simple custom control where in there is a image button on the control along with a label.
the problem that i am facing is that the image button appears just fine along with the specified properties. But somehow when i click on the image button it does not generate the click event. the page simply refreshes.
Can some one please tell me what is the mistake ???
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
//CreateChildControls();
AssociateValuesWithProperties();
ibFirst.RenderControl(output);
output.RenderEndTag();
}
protected override void CreateChildControls()
{
Controls.Clear();
// Set subcontrols behavior
//adding the event handlers to the image buttons
ibFirst.Click += new ImageClickEventHandler(ibFirst_Click);
}
private void AssociateValuesWithProperties()
{
ibFirst.ImageUrl = FirstImageSrcNormal;
ibFirst.AlternateText = FirstImageAltText;
ibFirst.ToolTip = FirstImageAltText;
}
protected void ibNext_Click(object sender, ImageClickEventArgs e)
{
this.CurrentPage++;
}
Thank you.

Ah!!
I found the solution to my problem.
in the function CreateChildControls() we should also add the controls to the control collection. once i did that the code worked just fine.
thanks

Related

Changing inner control as result of a event

I have a composite control like:
class MyControl : CompositeControl {
private Control _control1;
private Control _control2;
public bool RenderControl2 { get; set; }
/* Constructor to initialize controls*/
protected override void CreateChildControls(){
if(RenderControl2){
Controls.Add(_control2);
}else{
Controls.Add(_control1);
}
}
}
This works fine in scenarios where the value of RenderControl2 is set during Page_Init().
protected void Page_Init(object sender, EventArgs e){
if (!Page.IsPostBack){
myControl.RenderControl2 = MyMagicFucntion();
}
/* Works also when in Postback, but not required since the control keeps it state and only need to change state in the scenario below.*/
}
However, now we would like to set the value as a result of an event
protected void otherDropDow_SelectedIndexChanged(object sender, EventArgs e) {
myControl.RenderControl2 = otherDropDown.SelectedValue == "My Magic String";
}
This does not work since the control already executed CreateChildControls by the time the event fired. (Well, it does work during the next postback... :( )
I have tried to move the logic to the OnDataBinding event of the control. But this seems to have no impact on how the control actually show on the page.
/* DOES NOT RESOLVE THE ISSUE */
protected override void OnDataBinding(EventArgs e){
base.OnDataBinding(e);
/* _renderControl2HasChanged is set when RenderControl2 changes value
*/
if(_renderControl2HasChanged)
if(RenderControl2){
Controls.Remove(_control1);
Controls.Add(_control2);
}else{
Controls.Remove(_control2);
Controls.Add(_control1);
}
}
Instead of making the decision which control to display in CreateChildControls, you could evaluate the flag in OnPreRender and only change the visibility of the child controls, e.g.:
protected override void CreateChildControls()
{
Controls.Add(_control1);
Controls.Add(_control2);
}
protected override void OnPreRender(EventArgs e)
{
_control1.Visible = !RenderControl2;
_control2.Visible = RenderControl2;
}
In addition, you should save the value of RenderControl2 in the control state as described there. This way it will be persisted across postbacks.

Text box value are not accessing in asp.net c#

i have a textbox on .aspx page..On this page there is a user control .Inside this user contrl there is a button .I want o get the value of text box on button click which is not inside the user control .How can i do this
Please Help me .
write this line in you button click event of user control
protected void Button_Click(sender obj,EventArgs arg)
{
TextBox txtbox= (((MyPage)parent).FindControl("TextBoxid") as TextBox);
if(txtbox!=null)
(((MyPage)this.Page).FindControl("TextBoxid") as TextBox).Text;
//or
//(((MyPage)this.Parent).FindControl("TextBoxid") as TextBox).Text;
}
or
alternative is create the property in your page and access it in your user control
public string txtValue
{
get
{
return TextboxID.Text;
}
}
in button click event of user control
protected void Button_Click(sender obj,EventArgs arg)
{
string txtvalue = ((Mypage)this.Page).txtValue;
//or
//((MyPage)this.Parent).txtValue;
}
protected void MyButton_Click(object sender, EventArgs e)
{
string TextBoxValue;
TextBoxValue = MyTextBox.Text;
}
Is it what you want ?
Try use the following method,
((TextBox)USerControl.Parent.FindControl("txtbox")).Text
((TextBox)USerControl.Page.FindControl("txtbox")).Text
or
((YourPageType)USerControl.Page).TextBox.Text
With de-coupling in mind, I would recommend that if your user control needs to access information outside of it, then that information should passed in, not vice versa. The control shouldn't be responsible for where the information comes from, it just knows there is information. With this in mind, I would recommend bubbling the event to get the required information.
Event Bubbling
This will involve creating a new delegate, and then triggering it once the Button has been clicked, thus bubbling the event and allowing us to return the desired value, which in this case is the textbox value.
Step 1: Declare the delegate
// declare a delegate
public delegate string MyEventHandler(object sender, EventArgs e);
Step 2: Update the user control
// update the user control
public class MyUserControl : UserControl
{
// add the delegate property to your user control
public event MyEventHandler OnSomeButtonPressed;
// trigger the event when the button is pressed
protected void MyButton_Click(object sender, EventArgs e)
{
string someString = string.Empty;
if (this.OnSomeButtonPressed != null)
{
someString = this.OnSomeButtonPressed(this, e);
}
// do something with the string
}
}
Step 3: Update the page
// be sure to register the event in the page!
public class MyPage : Page
{
protected override void OnLoad(object sender, EventArgs e)
{
base.OnLoad(sender, e);
myUserControl.OnSomeButtonPressed += this.HandleUserControl_ButtonClick;
}
public string HandleUserControl_ButtonClick(object sender, EventArgs e)
{
return this.SomeTextBox.Text;
}
}

asp.net WebControl event order and ViewState

I have a custom class creating a dropdownlist control as below:
public class IHGridView : System.Web.UI.WebControls.WebControl
{
private string _dataSource = "not set yet";
public string DataSource
{
get { return _dataSource; }
set { _dataSource = value; }
}
}
EDIT:
protected override void OnInit(EventArgs e)
{
// VIewState is alive. When I select an option and submit, after postback it's selected value is the one I selected.
this.Controls.Add(_dropDownList);
}
or
protected override void CreateChildControls()
{
// VIewState is dead. When I select an option and submit, after postback it's selected value is the default one.
this.Controls.Add(_dropDownList);
}
So, now I come up with the result that I have to add control in "OnInit" void.
But, this "OnInit" is the first void that this class writes.
If I want to use a property like "DataSource" before, "OnInit" void...
How would I do that?
EDIT:
protected void Button1_Click(object sender, EventArgs e)
{
IHGridViewTest2.DataSource = "fired";
}
DataSource is set when the button in aspx page is fired.
why would you want to add _dropDownList twice? once in the OnInit should be enough, and OnInit is where it should be added if you want it in the control collection - thus having viewstate persisted and restored.
to access and bind _dropDownList for example, override the DataBind method - at which point all the properties will be available to you.
protected override void DataBind(){
base.DataBind();
_dropDownList.DataSource = this.DataSource;
_dropDownList.DataBind();
}
this is pseudo code, and has not been tested or validated
EDIT:
Call overriden DataBind method
protected void Button1_Click(object sender, EventArgs e)
{
IHGridViewTest2.DataSource = "fired";
IHGridViewTest2.DataBind();
}

ViewState["sample"] Variable not retaining value on postback in a composite control

I have created a composite control with sample details as follows. Basically, the first time on page load the control sets a view state variable and the problem is that on post back (when the button is clicked), the ViewState variable is null. I have researched extensively and I am not able to find a solution. I checked all the Microsoft recommended articles and also from other developers. This approach seem to work for everyone and I can't figure out what I'm doing wrong. If anyone can help, I would really appreciate it.
PS: This code may not work as it is only for illustrative purposes. but this is exactly what i'm doing in my code.
Public class Test : CompositeControl
{
private Button btnTest = new Button();
public string TestViewState
{
get
{
string s = (string)ViewState["test"];
return (s == null) ? String.Empty : s;
}
set
{
ViewState["test"] = value;
}
}
private void set()
{
TestViewState = "test";
}
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
set();
}
protected override void RecreateChildControls()
{
EnsureChildControls();
}
protected override void CreateChildControls()
{
base.Controls.Clear();
btnTest.ID = "btnTest";
btnTest.Click += new EventHandler(btnSubmitTest_Click);
if (!ChildControlsCreated)
Controls.Add(btnTest);
base.CreateChildControls();
}
protected override void Render(HtmlTextWriter writer)
{
btnSumbit.Render(writer);
}
protected void btnSubmitTest_Click(object sender, EventArgs e)
{
string test = TestViewState; // Viewstate value is null here!!!!!!
}
}
Are you sure that Page_Load is getting called? As far as I can remember that "notation" works only on pages and User Controls (didn't check that). Try overriding:
protected override void OnLoad(EventArgs e)
{
...
}
Test it with a Debugger.
Ok, the enableviewstate was disabled at the web.config level by another team member. Glad I found it. Thanks Arthur for confirming it worked for you.

asp c# dynamic button event in a custom class

I am creating a dynamic button in a custom class, outside of the .aspx codebehind. The custom class creates a Table object and generates a column of Buttons within that table. Once generated, the Table is loaded into a placeholder control. Everything is functioning well except for this problem:
How do I programmatically assign a Button Object a 'Click' event within the custom class?
MyButton.Click += new EventHandler(MyButtonClick);
This results in: 'The name 'MyButtonClick' does not exist in the current context' error.
I know it doesn't exist in the current context, but once the aspx page is rendered, the codebehind will include a method to handle 'MyButtonClick'. I don't know how store a Click event method name into a Button object from a custom class and pass it off to the aspx codebehind to be rendered.
You have to define an event in your custom control. Fire that event on button click so that your .aspx can handle it.
EDIT: Same principles apply to a custom class.
Control Code-Behind:
public delegate void ButtonEventHandler();
public event ButtonEventHandler ButtonEvent;
protected void Button1_Click(object sender, EventArgs e)
{
ButtonEvent();
}
.ASPX Code Behind:
protected override void OnInit(System.EventArgs e)
{
control1.ButtonEvent+=
new Control1.ButtonEventHandler (whatever_ButtonEvent);
}
protected void whatever_ButtonEvent()
{
//do something
}
Let's take this concept and apply it to a user control that has a textbox and two buttons. The user control is placed within a Gridview. When my code runs the method in my event handler method is always null. I think has to do w/the fact the a button is is in a user control which is in the gridview.
Here is my user control code.
public partial class User_Controls_GridViewFilter : System.Web.UI.UserControl
{
public event EventHandler UserControlButtonClicked;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
renderPage();
}
}
private void OnUserControlButtonClick()
{
if (UserControlButtonClicked != null)
{
UserControlButtonClicked();
}
}
protected void btnSearch_Click(object sender, EventArgs e)
{
OnUserControlButtonClick();
}
protected void btnReset_Click(object sender, EventArgs e)
{
OnUserControlButtonClick();
}
}
I register the control on the aspx page.
((User_Controls_GridViewFilter)gvMapLayer.HeaderRow.FindControl("FilterBox1")).UserControlButtonClicked
+= new ButtonEventHandler(User_Controls_GridViewFilter_UserControlButtonClicked);

Categories

Resources