Events in Asp.Net Webforms custom UserControl - c#

I've created a new Web User Control. This control has a button. On the click event of this button I raise an event in this way:
public partial class SearchDate : UserControl, IPostBackEventHandler
{
private static readonly object ObjEvent = new object();
// delegates
public delegate void VoidDelegate();
// events
[Category("Action")]
[Description("Azionato quando si preme il cancella nel filtro data")]
public event VoidDelegate CancelSearchDate
{
add
{
Events.AddHandler(ObjEvent, value);
}
remove
{
Events.RemoveHandler(ObjEvent, value);
}
}
protected virtual void OnCancelSearchDate()
{
var cancelEvent = (EventHandler) Events[ObjEvent];
if (cancelEvent != null)
{
cancelEvent(this, new EventArgs());
}
}
protected void BtnSearchDateCancelClick(object sender, EventArgs e)
{
OnCancelSearchDate();
}
protected void Page_Load(object sender, EventArgs e)
{
}
public void RaisePostBackEvent(string eventArgument)
{
OnCancelSearchDate();
}
}
I've created a delegate, an event and raise it on click of the button.
In another web form, where this control is hosted, i've added an handler to this event in this way:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
return;
InitDateFilter(SearchDate);
}
protected void InitDateFilter(SearchDate searchDateControl)
{
searchDateControl.CancelSearchDate += SearchDateControlCancelSearchDate;
}
void SearchDateControlCancelSearchDate()
{
// other stuff
currUtente.FiltroData = null;
SaveSession();
}
When I click to the button, it try to evaluate the event but it's always null.
I'm new in asp.net webforms and it seems to me strange that it not works well.
I've tried to raise the event in the simpler way (without the 'add' and 'remove' on the event definition), just calling the event if it isn't null but the behavior is the same.
Thanks

try to just override the OnInit event in the Page and add the handler to your event there.
like this:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
InitDateFilter(SearchDate);
}
Let me know if it helps

Related

Passing custom EventArgs as parameter of event

I am new to events and have been trying to create one and succeed but I have one question.
I have created event like this:
public class CustomControl : Panel
{
public event EventHandler OutputChanged; //My event
public CustomControl()
{
InitializeComponents();
}
//This event raises inside richtextbox which is inside my panel
private void OnTextChanged(object sender, EventArgs e)
{
if (OutputUpdate == OutputUpdate.OnTextChanged)
{
ValidateText();
//This is my created event
OnOutputChanged(new OutputChangedEventArgs { Asd = "Something" });
}
}
//void for this event
protected virtual void OnOutputChanged(OutputChangedEventArgs e)
{
EventHandler handler = OutputChanged;
if(handler != null)
{
handler(this, e);
}
}
}
//Custom event args class for my event
public class OutputChangedEventArgs : EventArgs
{
public string Asd { get; set; }
}
Above code shows declaration of my event with custom class for EventArgs parameter and now I will show you how I implement it in my code:
customControl1.OutputChanged += OnOutputChanged;
private void OnOutputChanged(object sender, EventArgs e)
{
OutputChangedEventArgs args = e as OutputChangedEventArgs;
MessageBox.Show(args.Asd);
}
As you can see in my implantation I pass EventArgs and then I convert it to OutputChangedEventArgs and reason for that is because if I try private void OnOutputChanged(object sender, OutputChangedEventArgs e) I get error No overload for 'OnOutputChanged' matches delegate 'EventHandler'
So my question is how can I directly pass my custom EventArgs class so I do not need to convert it inside method that handles it?
You can use the generic version of EventHandler that allows the specification of the argument type.
public event EventHandler<OutputChangedEventArgs> OutputChanged;

checkbox.Checked dosent update on other forms

I have 2 forms, UserInterface and Client I'm passing checkbox2.Checked info to Client but it only works however it was at launch. When I tick or untick and close and reopenClient it wont notice the change.
Modifiers is Public on checkbox2 at UserInterface form.
Here is Client code:
public partial class Client : Form
{
private UserInterface ui1;
public Client()
{
InitializeComponent();
}
public void CheckBoxCheck()
{
if (ui1.checkBox2.Checked == true)
{
MessageBox.Show("true");
}
else
{
MessageBox.Show("false");
}
}
}
If the checkbox is ticked at launch Client will show "true" but if I click it (untick) and run Client it will still show "true".
What do I need to add or modify so checkbox2 will be updated in realtime. Thank you.
Note: I'm pretty new with coding, explanations are appreciated.
I'll be building on noMad17's answer, you have to subscribe to your CheckBox event in your UserInterface form. But the change is that now we will send the CheckBox that was clicked in the event. So this code is for your UserInterface form:
public event EventHandler SomeEvent;
protected void OnSomeEvent(object sender, EventArgs e)
{
EventHandler eh = SomeEvent;
if(eh != null)
{
eh(sender, e);
}
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
OnSomeEvent(sender, e);
}
Now for the Client, it needs to know what a UserInterface is so we have to pass UserInterface to the Client in the constructor, otherwise it won't initialize. Also here we are gonna work out the CheckBox event that the parent form is gonna give us. And in the end we have to unsubscribe the event. So this code is for your Client:
public partial class Client : Form
{
private UserInterface ui1;
public Client(UserInterface ui1)
{
InitializeComponent();
this.ui1 = ui1;
ui1.SomeEvent += UI1_SomeEvent;
}
private void UI1_SomeEvent(object sender, EventArgs e)
{
//Your code...
CheckBox c = sender as CheckBox;
if(c.Checked == true)
{
MessageBox.Show("true");
}
else
{
MessageBox.Show("false");
}
}
private void Client_FormClosing(object sender, FormClosingEventArgs e)
{
ui1.SomeEvent -= UI1_SomeEvent;
}
}
Your Forms should be connected. It looks like ui1 is a different instance of UserInterface form.
There are different approaches to pass the data between forms and it depends on your demands.
For instance you could create UserInterface form inside of Client. And use the Show() method to show it.
You should probably be making use of the Checkbox.Checked event inside UserInterface class and then fire a custom event that your Client can subscribe to.
public event EventHandler<EventArgs> CheckboxCheckedChanged;
protected void OnCheckboxCheckedChanged(EventArgs e)
{
if (CheckboxCheckedChanged != null)
CheckboxCheckedChanged(this, e);
}
private void checkbox2_CheckedChanged(object sender, EventArgs e)
{
OnCheckboxCheckedChanged(e);
}
And then in Client:
ui1.CheckboxCheckedChanged += ui1_CheckboxCheckedChanged;
private void ui1_CheckboxCheckedChanged(object sender, CheckBoxEventArgs e)
{
// Your code here
}

What are techniques in ASP for communication from usercontrol to parent page?

I have having some trouble with communication from a usercontrol to the main page. The order in which events are raised means that the action on the user control occurs too late in the post back to have an effect on the main page.
For example, I have a button on a user control which, when pressed, raises a custom event that is being listened for on the main page. When the button is pressed the postback order is:
page_load - on the main page
page_load - on the usercontrol (the user control is loaded programitically by the main page page_load)
The button call back on the user control
The event call back method on the main page
By this point, it seems it is too late for anything the event call back method does to have any effect on the rendered page, for example I am trying to use it to change the usercontrol that is being displayed.
What other techniques can be used for this kind of communication?
Relevant code
Main page:
public string LastLoadedControl
{
get
{
return Session["LastLoaded"] as string;
}
set
{
Session["LastLoaded"] = value;
}
}
private void LoadUserControl()
{
string controlPath = LastLoadedControl;
ContentPlaceholder.Controls.Clear();
if (string.IsNullOrEmpty(controlPath))
controlPath = Utils.Paths.USERCTRL_BASE + "Main.ascx";
Control uc = Page.LoadControl(controlPath);
ContentPlaceholder.Controls.Add(uc);
}
protected void Page_Load(object sender, EventArgs e)
{
LoadUserControl();
if (!IsPostBack)
Utils.Events.redirectPage += Events_redirectPage;
}
private void Events_redirectPage(string path)
{
if (path.Equals("Main"))
{
//Session.Clear();
//Session.Abandon();
}
else LastLoadedControl = Paths.USERCTRL_BASE + path + ".ascx"
LoadUserControl();
}
User control
protected void profileBtn_Click(object sender, EventArgs e)
{
Utils.Events.triggerRedirectPage("Login");
}
Event
public class Events
{
public delegate void redirectEvent(string path);
public static event redirectEvent redirectPage;
public static void triggerRedirectPage(String path)
{
if (Utils.Events.redirectPage != null)
Utils.Events.redirectPage(path);
}
}
There are two approaches that you can follow.
Approach 1:
public interface IEventProvider
{
void TriggerEvent();
}
public class YourPage: Page, IEventProvider
{
// Other page methods
public void TriggerEvent()
{
// Your Implementation
}
}
public class YourUserControl : WebUserControl
{
protected void profileBtn_Click(object sender, EventArgs e)
{
IEventProvider eventProvider = this.Page as IEventProvider;
if(eventProvider != null)
eventProvider.TriggerEvent();
}
}
Approach 2:
public interface IEventProvider
{
// This does not have to be a boolean. You can use a string / enum / anything that suits your implementation
bool Trigger {get; set;}
}
public class YourPage: Page, IEventProvider
{
// Other page methods
protected override void OnLoadComplete(EventArgs e)
{
// This will be raised when all the events have fired for all the controls in the page.
if(this.Trigger)
TriggerEvent();
}
protected void TriggerEvent()
{
// Your code here
}
public bool Trigger
{
get;
set;
}
}
public class YourUserControl : WebUserControl
{
protected void profileBtn_Click(object sender, EventArgs e)
{
IEventProvider eventProvider = this.Page as IEventProvider;
if(eventProvider != null)
eventProvider.Trigger = true;
}
}

C# event Click TextBox

I have a usercontrol inheriting TextBox. But somehow the click event does not work. Other events work. How to make that work click?
this.Click += new EventHandler(AfyTransparentTextBox_Click);
private void AfyTransparentTextBox_Click(object sender, EventArgs e)
{
MessageBox.Show("KY-KY");
}
I don't know if this will be appropriate in your scenario but it works:
public class AfyTransparentTextBox : TextBox
{
protected override void OnClick(EventArgs e)
{
System.Windows.MessageBox.Show("KY-KY");
base.OnClick(e);
}
}

Event Handler is Always null

I have searched extensively on this, but cannot find the solution to my problem. I am trying to call a function in the code behind of a page from a user control on that page.
I have a web application that uses a master page. I am adding a user control that I wrote to one of the content pages. I added the user control to the aspx page by dragging and dropping it from the toolbox. I am able to see the user control from the code behind, but I cannot access the public functions. To fix that problem, I created an object of the user control in the code behind and used the LoadControl function. All of that seems to work fine.
The problem I am having is when I am trying to hook the into the EventHandler from the aspx page to the user control. Everything compiles and runs just fine, but I am not seeing anything happen on the page. I think the issue is that the EventHandler is always null.
User Control Code
public partial class ucBuyerList : System.Web.UI.UserControl
{
public delegate void BuyerSelectedEventHandler(object sender, EventArgs e);
public event BuyerSelectedEventHandler BuyerSelected;
private string name = "";
public string Name
{
get { return name; }
set { name = value; }
}
private string auid = "";
public string AUID
{
get { return auid; }
set { auid = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
}
private void OnBuyerSelected(EventArgs e)
{
if (BuyerSelected != null)
{
BuyerSelected(this, new EventArgs());
}
}
protected void lbBuyerList_SelectedIndexChanged(object sender, EventArgs e)
{
SetNameAndAUID();
OnBuyerSelected(e);
}
private void SetNameAndAUID()
{
name = lbBuyerList.SelectedItem.Text;
auid = lbBuyerList.SelectedItem.Value;
}
}
Parent Page Code
public partial class frmBuyerInformation : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Master.changePageTitle("Buyer Information");
buyerList.BuyerSelected += new ucBuyerList.BuyerSelectedEventHandler(buyerListControl_BuyerSelected);
}
void buyerListControl_BuyerSelected(object sender, EventArgs e)
{
DisplayBuyerInformation();
}
public void DisplayBuyerInformation()
{
tbName.Text = buyerList.Name;
tbAUID.Text = buyerList.AUID;
}
}
Can anyone see what I am doing wrong?
EDIT: This issue has been resolved. The code snippits above are now functional. If anyone runs into the issue I had, you can model the code above. Make sure that AutoEventWireup="true" in both the aspx and ascx pages. Thank you June Paik for your solution. Thank you Diego De Vita for your input as well.
I've been struggling with events for quite a while as well. Nowadays I always create them this way 'cause it's the only way I know it works. Haven't tested it with your code but here it goes anyway:
public partial class ucBuyerList : System.Web.UI.UserControl
{
public delegate void BuyerSelectedEventHandler(object sender, EventArgs e);
public event BuyerSelectedEventHandler BuyerSelected;
public string Name;
public string AUID;
protected void Page_Load(object sender, EventArgs e)
{
//Select the first buyer in the list when the user control loads
if (!IsPostBack)
{
lbBuyerList.SelectedIndex = 0;
}
}
private void OnBuyerSelected(EventArgs e)
{
BuyerSelectedEventHandler handler = BuyerSelected;
if (handler != null)
{
handler(this, new EventArgs());
}
}
protected void lbBuyerList_SelectedIndexChanged(object sender, EventArgs e)
{
Name = lbBuyerList.SelectedItem.Text;
AUID = lbBuyerList.SelectedItem.Value;
OnBuyerSelected(e);
}
}
In the parent page you can just call your function the same way you're doing it already.
It could be that Page_Load is too late in the page lifecycle to be using LoadControl and subscribing to the event. What happens if you move that code to the Page_Init method?

Categories