Navigating to the method behind an event in Visual Studio - c#

I am working with some legacy code that uses a lot of events. Basically, every method is called throught an event. All those events have only one subscriber.
When reading some code that raises an event, how can I quickly navigate to the code of this one subscriber?
e.g I am reading trough some code:
event xy DoStuff_Event;
void foo()
{
DoStuff_Event()
}
Now I want to know what code would be executed here.
So I click on DoStuff_Event()->"Find all references"
Then I search the references for the line DoStuff_Event += DoStuff_ForReal()
(There is always only one such line in this codebase)
Then I click on DoStuff_ForReal()->"Go to definition"
Now I finally can read the code that will be executed when DoStuff_Event() is called. Usually this code will consist of several further event calls, which in turn call even more events, so I repeat the whole process.
Is there a faster way to jump from the line DoStuff_Event() to the method definition of DoStuff_ForReal()?
For my case, when there is always only one subscriber for each event, it seems like this search could be automated.

Related

Why is the button's event handler not firing?

I have a button with an event handler attached to it; 2-clicking it in the designer takes me to the code. Nowhere is the handler being unhooked/detached.
Some code I expected to run apparently isn't, so I put a bunch of MessageBox.Show()s in the handler, even at the very beginning, but none of them display (Note: I can't step through the code; I have to do it this way (arggghhhh)).
Here's some of the code:
private void btnFind_Click(object sender, System.EventArgs e) // Find and list Records
{
MessageBox.Show("Made it into btnFind_Click 0"); //TODO: Remove after debugging
try
{
if (barcodeScanner != null)
{
// Turn off the listening
barcodeScanner.BarcodeScan -= new BarcodeScanner.BarcodeScanEventHandler(barcodeScanner_BarcodeScan);
}
MessageBox.Show("Made it into btnFind_Click 1"); //TODO: Remove after debugging . . .
What could be preventing this code from being executed?
UPDATE
Based on Mike C's idea, I added a MessageBox to the button_close handler. And when I click it, it does fire, but only after other code runs first; in this case, that other code doesn't prevent the Close_Click from (eventually) firing; with the Find button, though, it completely preempts it...IOW, I see the message from the Close button at the end when I click it, but I never see any of the messages in the Find button handler when I click it...
UPDATE 2
Oh my lanta/say it ain't so, Joe! What's happening is an event is being kicked off in the form's overloaded constructor, and somehow this event is always fired just then (after clicking the find button). The message I'm seeing, that preempts everything in the button event handler, takes place in a method which is called by processBarcode() which is called by processBarcode1(), which is invoked from barcodeScanner_BarcodeScan1(), which is called by barcodeScanner_BarcodeScan(), which is set up in frmEntry's overloaded constructor. If the previous coder had intended to drive me insane, he couldn't have done much better.
I guess there's a reason there's so much maintenance work "out there" or "out here": because there's so much bad broken code AND because the cats who make such a mess scratch a bunch of sand on it and walk away.
And this code is chock full of "huh?!?##$%^?!?" moments, where bizarre gyrations are not commented on at all, and yet there is this comment:
// Check connection
checkConnection();
The problem could be that the Click event of the button is not subscribed to properly. If there is no line resembling
this.btnFind.Click += new System.EventHandler(this.btnFind_Click);
in the Designer file of the form, that's it.

C# anyway to automatically break after a button click

If I have a project and I do not how design corresponds to the code is there a way to make the debugger break every time I press any button so I can quickly navigate to the right place in the code or am I asking for too much here?
You can make a call to System.Diagnostics.Debugger.Break() to tell any attached debuggers to break at that line.
If none are attached, Windows will try to launch any registered debuggers. If not are registered, you'll get an exception/crash of the application. So, don't leave it in the code in production :)
e.g. (as per icemanind's comment)
#if DEBUG
Debugger.Break();
#endif
If you want to break on a click of any button, it gets a bit tricky. The easiest thing is to write a Button wrapper class and override OnClick and put your Break call in there. For example:
public class ButtonWedge : Button
{
protected override void OnClick(System.EventArgs e)
{
Debugger.Break();
base.OnClick(e);
}
}
Once you add that class you can drag and drop it on the design surface. But, if you've already got code, you can edit the designer.cs file and replace System.Windows.Forms.Button with ButtonWedge.
Once in OnClick, you can see where the Click event will go by looking at the base classes Events array with the Control.EventClick key. That will contain a multicast delegate that you can look at the Method and Target properties to find out what has subscribed to this Click event. In other words, the name of the click handler at runtime will be:
string handlerName = base.Events[Control.EventClick].Target.GetType().FullName + '.'
+ base.Events[Control.EventClick].Method.Name;
It doesn't really put a break point in a particular Click event but lets you know what's going on and where...
If you meant a button on the program in the project then use Peter's answer. If you were asking can you make a button on the keyboard or mouse cause execution to break or pause, you can press Ctrl+Alt+Pause.
Why you cannot just DoubleClick on the button in design mode. Its open in code right on the function that handles a click event.

Prism CompositePresentationEvent fires twice

In my infrastructure i publish a event
this.eventAggregator.GetEvent<ReportAddedEvent>().Publish(report);
the report is a object
In my controller i subscribe to this event
this.eventAggregator.GetEvent<ReportAddedEvent>().Subscribe(this.OnReportAdded);
My problem is that the event fires twice. There is no other place in the entire code where the event is published so im certain that the event is not fired somewhere else and i can see it only fires once.
Anyone have a suggestion or have a solution to problem or knows where the problem lies.
I think the problem is that the code
this.eventAggregator.GetEvent<ReportAddedEvent>().Subscribe(this.OnReportAdded);
to subscribe to the ReportAddedEvent is executed two times.
You should check (by using a debugger and a breakpoint on the line) if it executes more than once.

How do I conserve program functionality and code after moving all controls into a tab control?

I had a working program (Windows Forms Project) complete with buttons, labels, textboxes e.t.c. and the underlying code.
In an attempt to shortcut my work, I decided to add tab controls and move everything in my main form into tab 1 (cut and pasted).
As you can imagine it didn't work. I then got rid of the tab conrol and pasted everything back into the main form but the program doesn't work anymore.
Can someone tell me what's wrong please?
I'm working in MS V studio 2008 express
Thanks.
I have done this many times, but I usually just drag them into the TabControl. Maybe in the cut and paste operation your controls have become unwired from the event declarations.
The event handlers that you coded are still there. However, they are not associated with the control any more. I'm not sure if you're using VB.Net or C#, but the fix is the same - it's manual and tedious if you have a bunch of controls, but not too difficult. Here are the instructions for fixing a single button control, and you'll have to apply the concepts across the board.
These instructions are specific to C#. I can give you VB instructions as well as I've done this plenty of times.
Double click on the button to generate a new event handler. If the button is named Button1, the original event handler was probably called Button1_Click. Now it should be Button1_Click1.
Delete the Button1_Click1 function and compile. You'll get errors and if you doible-click on the error in the error pane it will take you to the form,designer.cs file to a line that looks like:
this.Button1.Click += new System.EventHandler(this.Button1_Click1);
Change this to
this.Button1.Click += new System.EventHandler(this.Button1_Click);
to point to the previously existing event handler, and the event handler will be fixed.
Possibly some of the events had code lost.
If you do it again it will probably work.
For an alternative method see my message

Event Handling in winforms with multiple controls

Lets say we have a form consisting of 20+ controls, for example buttons.
We want to create handlers for the On-click event for all of them.
The usual way is to go to the designer and double-click each button to have it automatically create the function.
Another way is to create them yourself in code, after the InitializeComponent() function.
Is the difference between the two?
1) In performance
2) In speed
3) Garbage collecting
The first way is easy but lately I've been thinking about the second because its easy to see (in one place) what controls have what events handled without going to the designer which is a real pain if you have the controls cluttered...
Creating them through the designer is exactly the same as defining them in code yourself.
What actually happens is they are placed within the InitializeComponent() method on the form, which is normally in the designer.cs file. So it's there, it's just a little more hidden from the developer.
This means that neither performance/speed nor garbage collection will be affeted in anyway :)
As the other answers stated, there is little to choose between the tow methods other then coding style.
I have worked on a project where the Buttons themselves were attributed data that allowed a generic event handler to determine the action required. This alows the Event Handler code to be nice and simple e.g.
foreach(Control ctrl in this.Controls)
{
if(ctrl is Button)
{
(ctrl as Button).Click += // generic Event handler
}
}
The downside of this approach is that it tightly couples the button with the event handler code. But in a limited scope application with a set of buttons that perform the same function, this could be a useful techinque.
There's no difference in performance speed or garbage collection. Whether you write the event hander button.OnClick += MyHandler or you double click in the designer and he generates that for you, it's just the same.
There might be a difference in typing button.OnClick += MyHandler and the Visual Studio generated button.OnClick += new EventHandler(MyHandler). Since there's a constructor involved. But that's just a marginal difference.
Why would there be any difference ?
When you doubleclick the button in the designer, to create an eventhandler, VS.NET will generate code to attach the eventhandler to the Click event.
Actually, the generated code will be the same as the code that you'll write to attach the eventhandler to the event.

Categories