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);
Related
So, what I have here is 2 things. I have a static Button called MainButton that is already there permanently. What MainButton does is that it creates a dropdownlist and another button (setButton) dynamically. However when I create a onclickevent for setButton it does not seem to fire. I have seen several examples of this question and realised that I have to use Page_Init method for it to work, but I have no idea to implement this in my code and I really need help. (Sorry I am just a beginner at ASP.NET)
Here's my code :
public partial class createTest : System.Web.UI.Page
{
public DropDownList questionType = new DropDownList();
string selectedQuestion;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Page_OnInit(EventArgs e)
{
}
private void setButton_Click(object sender, EventArgs e)
{
Debug.WriteLine("Test");
}
protected void mainButton_Click(object sender, EventArgs e)
{
ContentPlaceHolder mainContent = (ContentPlaceHolder)this.Master.FindControl("ContentPlaceHolder1");
questionType.Items.Add("MCQ");
questionType.Items.Add("Open Ended");
mainContent.Controls.Add(questionType);
Create();
selectedQuestion = questionType.SelectedValue;
Debug.WriteLine(selectedQuestion);
}
void Create ()
{
ContentPlaceHolder mainContent = (ContentPlaceHolder)this.Master.FindControl("ContentPlaceHolder1");
Button setBtn;
setBtn = new Button();
setBtn.Text = "Set";
setBtn.Click += new EventHandler(setButton_Click);
mainContent.Controls.Add(setBtn);
}
}
}
Your problem is on the postback,
dynamic button and asp.net dosn't work good together.
I prefer adding the button and set it on visible="false" and set it to "true" on the click.
if you have multi buttons to add you can use repeater.
I have parent form called MainBackground and a user control named LoginUI. LoginUI is docked into the MainBackground.
I need to change enability of a button (InfoButton) located in parent form to "true" when user clicks on the button "Log in" in the control form.
But I can't access the parent button's properties.
Control form's button clicking event code:
private void button1_Click(object sender, EventArgs e)
{
MainBackground.infoButton.Enabled = true;
}
I tried solving it with parent controls, but still it doesn't seem to work.
Thanks for any help!
You can't access MainBackground.infoButton from LoginUI because infoButton is not static.
to solve this you could inject MainBackground trough a property like the example below
public partial class LoginUI : UserControl
{
public MainBackground MainBackground { get; set; }
...
}
in MainBackground you should initalize your LoginUI.MainBackground propery
loginUI1.MainBackground = this;
Make sure to make infoButton public
by setting the modifiers property to public
Now you can access MainBackground.loginUI1
private void login_Click(object sender, EventArgs e)
{
MainBackground.InfoButton.Enabled = true;
}
The method described in your question of Enabling the MainBackground forms InfoButton when the Login button is pressed is a common action. However, instead of directly binding the two items where the LoginUI Control is now forever bound to the MainBackground Form, you should de-couple the two by using Events.
The LoginUI Control should publish an event, perhaps called, LoginClicked. The MainBackground form can then subscribe to this event and execute whatever actions are required when the Login button is clicked.
In the LoginUI Control, declare an event:
public event EventHandler LoginClicked;
And, raise it whenever the Login button is pressed:
private void login_Click(object sender, EventArgs e)
{
OnLoginClicked(EventArgs.Empty);
}
protected virtual void OnLoginClicked(EventArgs e)
{
EventHandler handler = LoginClicked;
if (handler != null)
{
handler(this, e);
}
}
Finally, in the MainBackground form class, subscribe to the LoginClicked event
loginUI.LoginClicked += this.loginUI_LoginClicked;
Handle the LoginClicked event like this:
private void loginUI_LoginClicked(object sender, EventArgs e)
{
InfoButton.Enabled = true;
}
I have written on event in a user control and that user control used twice in a page. Now the problem is, I am getting the Event as null for the 2nd time. Why? How to resolve the issue? Please help.
My code like:
in ascx:
public delegate void OnGoButtonClick();
public event OnGoButtonClick btnGoClickHandler;
protected void btnGo_Click(object sender, EventArgs e)
{
if (btnGoClickHandler != null)
btnGoClickHandler();
}
In aspx:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
MyUserControl.btnGoClickHandler += new UserControls.LoanPicker.OnGoButtonClick(PopulateDataOnGo);
}
But for the 2nd user control it is always null.
Make sure to subscribe to the event from both controls.
Regarding your comment:
how to detect which user control being triggered
You need to supply the object that raised the event to the event handler. Start by altering the delegate signature to look like this:
public delegate void OnGoButtonClick(object sender);
public event OnGoButtonClick btnGoClickHandler;
protected void btnGo_Click(object sender, EventArgs e)
{
if (btnGoClickHandler != null)
btnGoClickHandler(this);
}
Now alter the event handler which in this case appears to be PopulateDataOnGo to accept the sender and check who raised the event from there:
public void PopulateDataOnGo(object sender)
{
if (sender is ControlType1)
{
}
else if (sender is ControlType2)
{
}
}
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;
}
}
I have a ascx page suppose page1.ascx in that I have a button click event handler
btnSave.Click +=
delegate
{
if (Save != null) Save(this, EventArgs.Empty);
};
and I have another ascx page suppose page2.ascx in that I have a button click
protected void btnEdit_Click(object sender, EventArgs e)
{
// want to call
btnSave.Click +=delegate
{
if (Save != null) Save(this, EventArgs.Empty);
};
}
I want to call btnSave click delegate(page1.ascx) on btnEdit(page2.ascx). Is it possible if yes then how?
If I understood what you mean, one way would be as below:
public class Control1 : UserControl {
public delegate void ButtonClickHandler(object sender, EventArgs e);
public ButtonClickHandler ButtonClickEvent {get;set;}
public void Save(object sender, EventArgs e) {
//do something
if (ButtonClickEvent != null) {ButtonClickEvent(sender, e);}
//do something
}
}
public class Control2 : UserControl {
protected override void OnLoad(EventArgs e) {
control1.ButtonClickEvent += YourMethod;
}
protected void YourMethod(object sender, EventArgs e) { // do something here ... }
}
Another way is to declare your button's event in the first control as property and assign your method in the 2nd control.
I'd recommend moving the code out of the code-behind and into a separate class, so that it is accessible to both .ascx files.