Changing Event Handler - c#

I have the following scenario: My application has a compiler that works correctly. The user chooses a control on the screen and write code in C # for this control. Before recording in the database, the user has the option to want if this event occurs before the code already written for the control or if the code you have written will have priority over the system code. My actual code:
public void ExecutaCodigo (string codigo)
{
ExecuteSnippetUser(codigo);
}
public void AtribuiEvento(Control c, string evento, string codigo, bool prioritario)
{
evento = evento.ToLower();
if(evento == "click")
{
if (!prioritario)
{
c.Click += delegate(Object sender, EventArgs e)
{
ExecuteSnippetUser(codigo);
// works fine!!! application and after, user code
};
}
else
{
c.Click -= delegate(Object sender, EventArgs e)
{
};
c.Click += delegate(Object sender, EventArgs e)
{
ExecuteSnippetUser(codigo);
};
}
}
}
What am I doing wrong ?

You'll have to hold onto a reference to the handler that you used to be able to remove it:
private ClickEventHandler handler;
public void AtribuiEvento(Control c, string evento, string codigo, bool prioritario)
{
evento = evento.ToLower();
if(evento == "click")
{
c.Click -= handler;
handler = delegate(Object sender, EventArgs e)
{
ExecuteSnippetUser(codigo);
};
c.Click += handler;
}
}

Related

Cannot assign to 'method' because it is a 'method group

I can't run my code because there is a error saying:
Cannot assign to 'OnNewLand' because it is a 'method group
This is strange because I have used the same structure as my other methods and there were no problem with them.
Here is my code.
private void CreateNewFlight()
{
string flightCode = ReadFlightCode();
//Create the new bidder
if (!string.IsNullOrEmpty(flightCode))
{
FlightWindow frm = new FlightWindow(Flightcode.Text);
frm.Show();
//Subscribe to the publisher's new bid and quit bid events
frm.NewStart += OnNewStartClick;
frm.NewChangeRoute += OnNewChangeRoute;
frm.OnNewLand += OnNewLand; <----Here is the error <-------
}
}
Cannot assign to 'OnNewLand' because it is a 'method group
My other window:
public event EventHandler<Start> NewStart;
public event EventHandler<ChangeRoute> NewChangeRoute;
public event EventHandler<Land> NewLand;
private void btnStart_Click(object sender, RoutedEventArgs e)
{
Start startinfo = new Start(this.Title);
OnNewStart(startinfo); //Raise event
btnLand.IsEnabled = true;
Routetxt.IsEnabled = true;
changebtn.IsEnabled = true;
btnStart.IsEnabled = false;
}
private void changebtn_Click(object sender, RoutedEventArgs e)
{
ChangeRoute changeinfo = new ChangeRoute(this.Title, Routetxt.Text);
OnNewChangeRoute(changeinfo); //Raise event
}
private void btnLand_Click(object sender, RoutedEventArgs e)
{
Land landinfo = new Land(this.Title);
OnNewLand(landinfo); //Raise event
}
//Raise Event
public void OnNewStart(Start e)
{
if (NewStart != null)
NewStart(this, e);
}
public void OnNewChangeRoute(ChangeRoute e)
{
if (NewChangeRoute != null)
NewChangeRoute(this, e);
}
public void OnNewLand(Land e)
{
if (NewLand != null)
NewLand(this, e);
}
You need
frm.OnNewLand += NewLand;
instead of
frm.OnNewLand += OnNewLand;
You might be interested to know what does it mean by method group. Visit this so thread.

How do I define custom eventargs for an event?

I would like to create custom Eventargs for a series of events. I am using a third party X/Y scope where I plot Strength vs frequency. This scope has the ability to place "Markers" on it which are just little triangles at various frequencies. These markers support events such as when the mouse enters the marker, a click is performed, and the mouse leaves the marker. So for two markers, here is the code:
private void createEvents()
{
this.scope2.MarkerGroups[0].Click += new EventHandler(Marker0_Click);
this.scope2.MarkerGroups[0].MouseEnter += new EventHandler(Marker0_Enter);
this.scope2.MarkerGroups[0].MouseLeave += new EventHandler(Marker0_Leave);
this.scope2.MarkerGroups[1].Click += new EventHandler(Marker1_Click);
this.scope2.MarkerGroups[1].MouseEnter += new EventHandler(Marker1_Enter);
this.scope2.MarkerGroups[1].MouseLeave += new EventHandler(Marker1_Leave);
}
// And now the event handlers
private void Marker0_Click(object sender, EventArgs e)
{
//do something;
}
private void Marker0_Enter(object sender, EventArgs e)
{
//do something
}
private void Marker0_Leave(object sender, EventArgs e)
{
// do something
}
private void Marker1_Click(object sender, EventArgs e)
{
//do something;
}
private void Marker1_Enter(object sender, EventArgs e)
{
//do something
}
private void Marker1_Leave(object sender, EventArgs e)
{
// do something
}
Now this is fine for two markers....but I need 80 of them. I could just write the whole thing out but there has to be a better way. So I started like this:
private void createMarkerEvents()
{
for (int i = 0; i < 80; i++)
{
this.scope2.MarkerGroups[i].Click += new EventHandler(Marker_Click);
this.scope2.MarkerGroups[i].MouseEnter += new EventHandler(Marker_Enter);
this.scope2.MarkerGroups[i].MouseLeave += new EventHandler(Marker_Leave);
}
}
private void Marker_Click(object sender, EventArgs e)
{
//do something;
}
private void Marker_Enter(object sender, EventArgs e)
{
//do something
}
private void Marker_Leave(object sender, EventArgs e)
{
// do something
}
So the question is how can I pass the actual marker number from the events to the event handlers?
There has got to be a way.
Thanks, Tom
If you want to identify marker group you may cast object sender to a MarkerGroup object
private void AnyMarker_Click(object sender, EventArgs e)
{
MarkerGroup group = (MarkerGroup)sender;
int indexOfMarkerGroup = this.scope2.MarkerGroups.IndexOf(group);
//do something;
}
OFF: You should define a custom EventArgs class:
public class MyEventArgs : EventArgs
{
public int MyCustomProperty {get;set;}
}
Then use it in your event:
public event EventHandler<MyEventArgs> ButtonPressed;
Fire event using custom args:
if(ButtonPressed != null)
{
ButtonPressed(this, new MyEventArgs { MyCustomProperty = 1 });
}
EDIT
Full example:
private void createMarkerEvents()
{
for (int i = 0; i < 80; i++)
{
this.scope2.MarkerGroups[i].Click += new EventHandler(Marker_Click);
this.scope2.MarkerGroups[i].MouseEnter += new EventHandler(Marker_Enter);
this.scope2.MarkerGroups[i].MouseLeave += new EventHandler(Marker_Leave);
}
}
private void Marker_Click(object sender, EventArgs e)
{
// When markergroup fires and event, it passes reference to itself as `sender` parameter
// so we can get access it
MarkerGroup mg = (MarkerGroup)sender; // this marker has fired a click event
// Now you know which marker has fired event
// if you want to determine it's index in MarkerGroups collection:
int index = this.scope2.MarkerGroup.IndexOf(mg);
// now you know MarkerGroup and it's index
}
private void Marker_Enter(object sender, EventArgs e)
{
//do something
}
private void Marker_Leave(object sender, EventArgs e)
{
// do something
}

NullReferenceException when subscribing to an event in the user control on the main form

On my User Control I have created an event to notify my main form that a tab control must switch its tab. This event must be triggered on a button's click on the user control. (I have a very similar event in another User Control that is working fine)
In my user control:
public delegate void EventHandler(object sender, EventArgs args);
public event EventHandler TabChangeRequested = delegate { };
protected void OnTabChangeRequested()
{
if (TabChangeRequested != null)
{
TabChangeRequested(this, new EventArgs());
}
}
private void btnBackToSelectType_Click(object sender, EventArgs e)
{
this.OnTabChangeRequested();
}
In my main form:
public FormMain()
{
InitializeComponent();
myUserControl.TabChangeRequested += (sender, args) => { ChangeRunTabToType(); };
}
private void ChangeRunTabToType()
{
if (this != null)
this.ChangeTabIndex(metroTabControlRun, 1);
}
When I run my program I get a NullReferenceException on the line
myUserControl.TabChangeRequested += (sender, args) => { ChangeRunTabToType(); };
Does anyone know where it comes from?
If myUserControl isn't instantiated yet (and that's what is null), then I'd recommend moving:
myUserControl.TabChangeRequested += (sender, args) => { ChangeRunTabToType(); };
to after where you are creating/assigning myUserControl!

how to run the event of user control not regular

I have a user control with some buttons (tmNewItem, tmEdit, tmInsert)
I write a clickButton event for them.
for example:
public void btnEdit_Click(object sender, EventArgs e)
{
btnNew.Enabled = false;
btnEdit.Enabled = false;
}
I used this user control in another project and write another method for the buttons and assign it to the usr control:
public void DTedit(object sender, EventArgs e)
{
}
private void UserControl_Load(object sender, EventArgs e)
{
DT_Navigator.btnCancel.Click += new EventHandler(DTedit);
}
and now, when I run the project and press btnEdit button, the first time, btnEdit_Click will execute and after that DTedit. can i change it? I mean the first time DTedit (that I define it in my project) run, and after it btnEdit_Click (that I define it in the user control) run?
how can I do that?
Try this
public void DTedit(object sender, EventArgs e)
{
//Place your code here
DT_Navigator.btnCancel.Click -= new EventHandler(DTedit); //This will remove handler from the button click and it will not be executed next time.
}
private void UserControl_Load(object sender, EventArgs e)
{
DT_Navigator.btnCancel.Click += new EventHandler(DTedit);
}
Suggested Code
//User control
public event CancelEventHandler BeginEdit;
public event EventHandler EndEdit;
private btnYourButton_Click(object sender, EventArgs e)
{
CancelEventArgs e = new CancelEventArgs();
e.Cancel = false;
if (BeginEdit != null)
BeginEdit(this, e);
if (e.Cancel == false)
{
if (EndEdit != null)
EndEdit(this, new EventArgs);
//You can place your code here to disable controls
}
}

Program wait for an event to occur in c#

I want this part of my program (I showed in code by "//" sign before the line) to wait until button3 is clicked to resume.
private void button2_Click(object sender, EventArgs e)
{
if (this.textBox3.Text != "")
{
this.listView1.Items.Clear();
//this.listView1.Items.Add(this.textBox3.text);
}
}
Seems like you want something like this:
private void button2_Click(object sender, EventArgs e)
{
if (this.textBox3.Text != "")
{
this.listView1.Items.Clear();
button3.Click += Function;
}
}
private void Function(object sender, EventArgs e)
{
this.listView1.Items.Add(this.textBox3.text);
button3.Click -= Function;
}
So we'll start out with this helper method that produces a task that will be completed when a button is clicked:
public static Task WhenClicked(this Button button)
{
var tcs = new TaskCompletionSource<bool>();
EventHandler handler = null;
handler = (sender , args) =>
{
tcs.SetResult(true);
button.Click -= handler;
};
button.Click += handler;
return tcs.Task;
}
Using this, along with await from C# 5.0, we can create code that reads just like what you requested, even though it produced code similar to what the other answers have (thus maintaining asynchrony and not blocking the UI thread).
private async void button2_Click(object sender, EventArgs e)
{
if (this.textBox3.Text != "")
{
this.listView1.Items.Clear();
await button3.WhenClicked();
this.listView1.Items.Add(this.textBox3.text);
}
}

Categories