HI could anyone advice how to solve this error?
I got the response from this thread here but unfortunately there is no more response from the author. So i decided to post here again with his solution.
ERROR: Error 1 Cannot implicitly convert type 'project1.Utility.AdminController.AdminControllerEvent' to 'System.EventHandler'
Error happen when i want to hook the
//btnDelete.Click += new AdminControllerEvent(btnDelete_Click);
namespace project1.Utility
{
public partial class AdminController : UserControl
{
public delegate void AdminControllerEvent(object sender, AdminControllerEventArgs e);
public event AdminControllerEvent SaveClick;
public event AdminControllerEvent DeleteClick;
public AdminController()
{
InitializeComponent();
//btnDelete.Click += new AdminControllerEvent(btnDelete_Click);
}
private void btnDelete_Click(object sender, AdminControllerEventArgs e)
{
if (DeleteClick != null)
{
if (MessageBox.Show(CoreMessages.DeleteAsk, CoreMessages.DeleteAsk, MessageBoxButtons.OKCancel) == DialogResult.OK)
{
DeleteClick(sender, e);
if (AdminControllerEventArgs.Success)
{
MessageBox.Show(CoreMessages.DeleteSuccess, CoreMessages.Successful, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show(CoreMessages.DeleteFailed, CoreMessages.Failed, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
}
}
}
public class AdminControllerEventArgs : EventArgs
{
public static bool Success;
public AdminControllerEventArgs()
: base()
{
Success = true;
}
}
}
In my Form delete UI
private void adminController_DeleteClick(object sender, AdminControllerEventArgs e)
{
Repository.Delete(user);
}
The event Click expects a handler implementing the signature described by System.EventHandler. That won't work - you have to change the signature or implement your own additional handler for Click that raises another event calling your custom handler. I'm not really sure what you're tryin to do here mixing event handler code with other UI messages etc.
The problem here is the signature of the method. The button click event has no event data to pass and by convention they have two parameters.
Since it has no event data to pass it uses EventArgs,so since you have made your implementation the Button Click is unaware of that and so the error
Button.Click will raise Click event with plain EventArgs arguments. You can't expect Click(object sender, EventArgs e) to work with more specific method signature (using AdminControllerEventArgs arguments). How do you convert EventArgs to AdminControllerEventArgs?
Imagine it worked tho. What happens when:
Button.Click creates new EventArgs()
Button.Click calls your btnDelete_Click(this, args)
args are expected to be of type AdminControllerEventArgs
...but are in fact EventArgs
your code in btnDelete_Click tries to access args.Success property
...which isn't there, because EventArgs doesn't have one
Unfortunatelly, you'll need a workaround for this.
Related
I made a derived class from Button control class. When I use the control, I need to make to be prevented from invocation in some situation. The situation is already defined in the derived class, myClick function. I guessed there is a way like setting e.Cancel = true, but I can't. Can you give a simple suggestion to solve this task?
public class SButton : Button
{
public SButton() : base()
{
Click += new System.EventHandler(myClick);
}
private void myClick(object sender, EventArgs e)
{
if( meHandsome )
{
// here I want to prevent no more event invocation!
}
}
}
public partial class UTeachAdvanced : DevExpress.XtraEditors.XtraUserControl
{
private void UTeachAdvanced_Load(object sender, EventArgs e)
{
SButton btn = new SButton();
Controls.Add(btn);
btn.Click += new EventHandler(delegate(object sender, EventArgs args)
{
Console.Write("ugly");
}
}
}
The situation is already defined in the derived class.
The Click event raises by Control.OnClick method. To prevent raising Click event, you can override OnClick and call base.OnClick only if the criteria to prevent the click is not true:
public class SampleButton : Button
{
protected override void OnClick(EventArgs e)
{
if(!criteriaToPrevent)
base.OnClick(e);
}
}
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)
{
}
}
In this code, Form1 supposes to listen to the Add button in user control and displays the message in the Form1. When i run it in a debugging mode, it return NullPointerReference at clicked(this,e). Can someone help me with this? thanks.
User Control:
public event EventHandler clicked;
public DataInput()
{
InitializeComponent();
Add.Click+= new EventHandler(Add_Click);
}
private void Add_Click(object sender, EventArgs e)
{
items = textBox1.Text.PadRight(15) + textBox2.Text.PadRight(15) + textBox3.Text.PadRight(15);
clicked(this, e);
}
Form:
public Form1()
{
InitializeComponent();
dataInput.clicked+= new EventHandler(OnChanged);
}
public void OnChanged(Object sender, EventArgs e)
{
MessageBox.Show("testing");
}
Exception is thrown because there are no subscriptions to your clicked event. Either Form1 is no yet created, maybe you're using different constructor, or you unsubscribed later.
Anyway, you should always check for subscription before invoking an event delegate.
Change your code in Add_Click to:
EventHandler evnt = clicked;
if (evnt != null)
evnt(this, e);
not sure why the "clicked" EventHandler is null.
You should always make sure the EventHandler has been initialized before using.
i.e.
if(clicked != null)
{
clicked(this, e);
}
I can't figure out how to do this, heres sample code. Of what I wish to do.
public Class MainForm : Form
{
MyUserControl MyControl = new MyUserControl;
private void Button_Click(object sender, EventArgs e)
{
//Create MyEvent
}
}
public Class MyUserControl : UserControl
{
//listen for MyEvent from MainForm, and perform MyMethod
public void MyMethod()
{
//Do Stuff here
}
}
Step 1) Expose an event on MainForm... say..
public event Action simpleEvent
Step 2) Give MyUserControl a constructor that takes an instance of MainForm and bind an action to that event
public MyUserControl(MainForm form) {
form += () => Console.WriteLine("We're doing something!")
}
Step 3) raise the event in MainForm.Button_Click
if(simpleEvent != null) simpleEvent();
Note: You could register your own delegates and work with something other than lambda expressions. See http://msdn.microsoft.com/en-us/library/17sde2xt.aspx for a more thorough explanation
Your end result would look like...
public Class MainForm : Form
{
public event Action MyEvent;
MyUserControl MyControl = new MyUserControl(this);
private void Button_Click(object sender, EventArgs e)
{
if(simpleEvent != null) simpleEvent();
}
}
public Class MyUserControl : UserControl
{
//listen for MyEvent from MainForm, and perform MyMethod
public MyUserControl(MainForm form) {
simpleEvent += () => MyMethod();
}
public void MyMethod()
{
//Do Stuff here
}
}
This is how to delegate to an event of a private member, so the outside can listen to it.
public event EventHandlerType EventHandlerName
{
add
{
this._privateControl.EventHandlerName += value;
}
remove
{
this._privateControl.EventHandlerName -= value;
}
}
Another option would be to have an event in your form class:
public event EventHandler MyEvent;
And listen to the private member's event:
this._customControl.SomeEvent += this.SomeEventHandler;
With this:
private void SomeEventHandler(object sender, EventArgs e)
{
if (this.MyEvent != null)
{
this.MyEvent(this, e);
}
}
The usage from the outside in both cases will be the same:
var form = new Form1();
form1.MyEvent += (o, e) => { Console.WriteLine("Event called!"); };
The bottom line is the you must implement functionality inside your form to allow the outside subscribe/listen to inner events.
//listen for MyEvent from MainForm, and perform MyMethod
That's the wrong way around. Publishing an event in control is useful, the control cannot possibly guess how it is going to get used. It however most certainly should not know anything about an event that may or may not be available in the form that it gets dropped on. That has the nasty habit of blowing up when the form just doesn't (yet) have the event. The bad kind too, a crash at design time that puts up the White Screen of Darn and prevents you from fixing the problem.
A form doesn't have to guess, it knows exactly what controls it has. So where ever in the form you might want to raise the event, just call the control's MyMethod method directly. And if that's wrong for some reason, like removing the control but not the call, then you just get a compile error that's easy to fix.
I am a person learning c#, and I have a program with a Parent form and a Child form. I want the child form to raise an event so that the Parent form can do something. I copied some code, but I am not smart enough to see what is wrong. I don't know how to correctly code the event in the child form. The error is DatasourceUpdated is not defined. Can anyone help me out with a suggested fix?
In the Child form I have
public partial class Form2 : Form
{
public EventHandler DataSourceUpdated;
...
private void button2_Click(object sender, EventArgs e) //Done button
{
if (this.DataSourceUpdated != null) //raise the event
{
this.DatasourceUpdated();
}
this.Close();
}
In the parent form I have this:
private void myAddRecord()
{
string myID = string.Empty;
string myMessage = "Insert";
Form2 myForm = new Form2(myID, myMessage);
Form2.DatasourceUpdated += ChildUpdated;
myForm.Show();
Right now, you're declaring an EventHandler, not an event. Change this to:
public partial class Form2 : Form
{
public event EventHandler DataSourceUpdated;
...
private void button2_Click(object sender, EventArgs e) //Done button
{
if (this.DataSourceUpdated != null) //raise the event
{
this.DataSourceUpdated(this, EventArgs.Empty);
}
this.Close();
}
Also, when you go to subscribe to your event, you need to subscribe to the event on the instance, not on the class:
Form2 myForm = new Form2(myID, myMessage);
myForm.DataSourceUpdated+= ChildUpdated;
myForm.Show();
This is because the event is declared at the instance level, not statically.
Form2.DatasourceUpdated += ...
you are trying to attach your handler to the class try this instead
myForm.DatasourceUpdated += ...
Your code looks right, as far as I can tell, as long as you have an actual handler; you have not included that in your code. ChildUpdated needs to be a method that with the signature void (object sender, EventArgs e), and you should also raise the event like that this.DataSourceUpdated(this, null);
The signature is being specified by the fact that you're declaring the event as being handled by System.EventHandler, which has that signature. You can create your own delegates as well, if you want it to receive some special parameters or no parameters at all.
Also, you have an inaccurate casing in your example, this.DatasourceUpdated -> this.DataSourceUpdated, but I'll assume that's just in your example...?
.NET events have both a "sender" object and an "EventArgs" object. These need to be included when your event is called.
for example:
private void button2_Click(object sender, EventArgs e) //Done button
{
if (this.DataSourceUpdated != null) //raise the event
{
this.DatasourceUpdated(this, EventArgs.Empty);
}
this.Close();
}
First of all there's a small typo: DatasourceUpdated vs DataSourceUpdated. See the capital S? Also, don't forget the args and to declare the DataSourceUpdated as an event:
public event EventHandler DataSourceUpdated;
...
this.DataSourceUpdated(this, EventArgs.Empty);
Another problem I notice is that your calling a static member when you should be calling an instance member:
Form2.DatasourceUpdated += ChildUpdated;
to
myForm.DatasourceUpdated += ChildUpdated;