Excel add-in ribbon click events bubbling - c#

I am following this walkthrough on MSDN: Creating a Custom Tab by Using the Ribbon Designer
Looking at steps 3 and 4:
In step 3 it adds an event handler to the ribbon_Load function, basically adding a click event to a button in the ribbon:
private void MyRibbon_Load(object sender, RibbonUIEventArgs e)
{
this.button1.Click += new RibbonControlEventHandler(this.button1_Click);
}
Then, in step 4 they add another event handler in the way that I am more used to, like so:
private void button1_Click(object sender, RibbonControlEventArgs e)
{
MergeReportInterface ui = new MergeReportInterface();
ui.ShowDialog();
}
I am not really understanding the purpose of this, because all it does is cause the event to fire twice. If I comment out the event handler that was added to the load function the event occurs once.
Could someone please explain to me what the point of this is? if there is any, or if there is some error on the MSDN site. What should be the proper way to handle a ribbon click event?

private void button1_Click(object sender, RibbonControlEventArgs e)
{
MergeReportInterface ui = new MergeReportInterface();
ui.ShowDialog();
}
This is not adding an event handler. This is the method that your event will call.
this.button1.Click += new RibbonControlEventHandler(this.button1_Click);
This is saying 'When button1 fires its Click event, call this.button1_Click'.
Your code only sets up one event handler, it should only fire once.
However, it's likely you created the button1_Click method by double clicking a button on your form designer. This, behind the scenes, adds an additional event handler. This is why you're getting the event fired twice.
So you have two options:
Go back into the IDE and remove the click handler via your form designer. Go to your code and manually write the method button1_Click.
OR
Remove this line: this.button1.Click += new RibbonControlEventHandler(this.button1_Click);, as VisualStudio is doing that for you automatically.

Related

Why does Message Box appear twice when event is called.

So I've been following the Visual Studio tutorials that microsoft has available (more specifically the math quiz one found at https://msdn.microsoft.com/en-us/library/vstudio/dd492172.asp)
but I deviated a bit from the tutorial because I wanted to see if I could create an event and call it using the EventHandler delegate though it might not be the best solution.
public event EventHAndler quizStarted;
here is the code for creating the event.
now in the method
public Form1()
{
this.quizStarted += new System.EventHandler(this.showThatTheQuizStarted);
InitializeComponent();
}
I have initialized my event with an instance of the EventHanlder that points to my showThatTheQuizStarted method.
public void showThatTheQuizStarted(object sender, EventArgs e)
{
MessageBox.Show("Quiz Has Started");
}
and finally when the start button is pressed I call the quizStarted event as shown below.
private void startButton_Click(object sender, EventArgs e)
{
startButton.Enabled = false;
quizStarted(this, new EventArgs());
this.StartTheQuiz();
}
in this order the message box goes away after hitting okay once, also in StartTheQuiz() nothing calles a message box directly or indirectly.
but if I place the this.quizStarted += new System.EventHandler(this.showThatTheQuizStarted); line into the startButton_Click method, the message box appears twice one right after the other.
Though I found a solution I would like to know why this happens if I place this line of code out of the constructor.
If...
this.quizStarted += new System.EventHandler(this.showThatTheQuizStarted);
... gets called multiple times, as would happen if you move it inside a button Click event handler method, then you are in fact adding and registering a new event handler every time.
In other words, when quizStarted is invoked, it may call multiple event handlers, depending on how many you choose to register. If you register the same event handler multiple times, then it will get called as many times.
That's why you want to leave the registration in a place where you are guaranteed to register the event handler once and only once.

Fire an event within another event

I need help on firing an event within C#
Basically I have a onclick event that fires when you click on a checkbox
void OnClick(object sender, RoutedEventArgs e)
{
...
}
I need help on firing an event within C#
Basically I have a onclick event that fires when you click on a checkbox
void OnClick(object sender, RoutedEventArgs e)
{
...
}
However, I need to fire this event once another event has been fired, so within this new event, is it possible I can fire the above one?
private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
switch(dataGrid.Name)
{
case "Customer"
//fire OnCLick Event
break;
}
}
I have tried something like
??? += new MouseEventHandler(OnClick);
But I am not sure if this will actually work.
Yes you can, but only if the event is in your own class. You can't even raise a base class' event. You have a put a method in the base class to raise the event, and then call that.
The code you put there is adding another event handler, not raising an event; you don't need to do that.
If it's a button, use btnDoSomething.PerformClickEvent (winforms)
If the handler is in your code, you can call it without raising the event (commenters assume that this is what you want to do but in reaslity there are many cases where you'd need more than this) btnDoSomething_Click(null, null) - null usually works because handler code rarely cares about the sender or arguments and if you don't reference them, you don't need them.
If you can use #4, you can also refactor as mentioned. Usually not needed. But usually so easy to do you it's worth doing for clarity anyway.
For objects that map from Windows widgets of anysort, check out the SendMessage and PostMessage API calls. Wayyyy beyond the scope of this answer, though. Doesn't apply to non-windows-backed objects (but your sample implies windows).

How to generate events automatically for buttons without creating manually from properties if there are 'n' number of buttons?

IDE: Visual Studio 2010
Language: c# .net
I am generating events for buttons manually from properties. But, its becoming very lengthy process if there are suppose 20 buttons doing the same task like 'Mouse Hover' and 'Mouse Leave' . So, is there a way to copy events for all the other buttons ?
You can subscribe all your buttons to same event handler:
foreach(var button in Controls.OfType<Button>())
{
button.MouseHover += Button_MouseHover; // add handler
button.MouseLeave += Button_MouseLeave;
}
In that handler you can determine which exact button raised even by casting event source to button type:
private void Button_MouseHover(object sender, EventArgs e)
{
var button = (Button)sender; // sender is one of buttons
// use button.Name
}
Code above subscribes to events of all buttons. But if you want to filter them (e.g. by name) you can add filtering:
Controls.OfType<Button>().Where(b => b.Name.StartsWith("foo"))
Buttons can all share the same event, there's no need to have a seperate event for each button if they're doing similar tasks. (The object sender parameter will give you the Control which was clicked.
IF you select all the buttons (by keeping the ctrl key pressed) in the designer, you can then easily assign 1 event to all 20 buttons
In life you will not find shortcuts for everything,
In short there is no shortcut, but yes as mentioned in other post if you have same event handler and same action to be taken then this will help you reduce your work.
You don't have to do this manually, you can add event handlers from code as well. Also, if the logic is quite similar for all the buttons then you can use single event handler for all of them. Every event handler has sender property what will be set to the button that caused event.
Simple example would be something like this:
//at first assign event handlers
button1.Click += new EventHandler(Button_Click);
button2.Click += new EventHandler(Button_Click);
//single event handler
private void Button_Click(object sender, System.EventArgs e)
{
// Add event handler code here.
Debug.WriteLine("You clicked: {0}", sender);
}

Can't call event from button

I have three different events:
form_load
button_click
pnlTiles_Paint
My button click event I have:
private void btnUpdate_Click(object sender, EventArgs e)
{
pnlTiles.Paint += pnlTiles_Paint;
}
My form_load event I have:
private void frmMain_Load(object sender, EventArgs e)
{
pnlTiles.Paint += pnlTiles_Paint;
}
Now my problem is that the event gets called when I use it in form_load but when I use it in the button event; it just skips over the event, I tried to step into the event when debugging the button click. But I made no progress on trying to figure out why the event doesn't get called from the button.
As others have pointed out, pnlTiles.Paint += pnlTiles_Paint; means you are subscribing to the Paint event on the control pnlTiles. What this means is that every time pnlTiles raises the Paint event, the method specified by pnlTiles_Paint will get called. What causes Paint to get fired? According to msdn,
The Paint event is raised when the control is redrawn. It passes an instance of PaintEventArgs to the method(s) that handles the Paint event.
So what's probably happening is that pnlTiles raises the Paint event AFTER the main form raises the Load event (since this is the first time pnlTiles is getting drawn on the screen) which is why your handler ends up getting called.
However, clicking on a button does not cause pnlTiles to get redrawn and the Paint event to get raised, hence your handler does not get called.
If for some reason, after you have hooked up your handler in the Button's click handler, pnlTiles needs to be redrawn, pnlTiles_Paint will get called. You can test this by calling pnlTiles.Invalidate() in the Button's click handler after subscribing to pnlTile's Paint event.
private void btnUpdate_Click(object sender, EventArgs e)
{
pnlTiles.Paint += pnlTiles_Paint;
pnlTiles.Invalidate();
}
Since you're a little fuzzy on the basics of events, it might be worth reading these articles:
Jon Skeet - Events
MSDN - Events.
Also, make sure to read cgijbels comment on this post about not subscribing to the same event multiple times.

Detecting a Mouse click on selecting a row in dataGridView

I am having trouble getting my application to work correctly. I am trying to select a row in a datagridview with the mouse. I need to save the index of this row to allow me to navigate around the selected row.
I have been looking at DataGridView.CellMouseClick Event (Link) But I am unable to ensure that the event handler is associated with the CellMouseClick event.
My code for this so far is simple, Im just trying to see if its detecting mouse clicks:
public event DataGridViewCellMouseEventHandler CellMouseClick;
private void DataGridView1_CellMouseClick(Object sender, DataGridViewCellMouseEventArgs e)
{
MessageBox.Show("Mouse clicked in the datagridview!");
}
Can anyone point out where I may be going wrong. Any help would be great!
You need to "wire up" the event.
If your DataGridView is called DataGridView1 then you need the following line of code in either the constructor for your form, the designer (if you add the event handler via the designer) or in the Load event:
DataGridView1.CellMouseClick += DataGridView1_CellMouseClick;
This attaches the event handler in your code to the event.
Your current sample looks like this:
public event DataGridViewCellMouseEventHandler CellMouseClick;
private void DataGridView1_CellMouseClick(Object sender, DataGridViewCellMouseEventArgs e)
{
MessageBox.Show("Mouse clicked in the datagridview!");
}
There is no need to redeclare the event (public event DataGridViewCellMouseEventHandler CellMouseClick;) unless you are building your own user control that will host a DataGridView and you effectively want to "wrap" or "rebroadcast" that event.

Categories

Resources