How add something to do when own ErrorHandler event happens? - c#

It was firs time I have used delegate and event. I made an error handler event for Memory Game program. The program has a "lot" of SQL operation. The event functioning wery well. I subscribe a MessageBox "caller void" to print errormessages out in the Main Form. (It was a surprise for me that I had to subscribe this printout void only in the Main and every Form errors are printed out by this little void.)
I have problem with error handling. When I handled the problems with Exceptions I could handle everything to the very end (if Exception not null do....).
Delegate and event is very usefull but I dont know how close the actual form or simply make something to do when an error happens.
I have tried to implement this.close() after MessageBox printed out the message but it closes the whole program.
private void MessageBoxPopUp(string errorMessageForMessageBox)
{
MessageBox.Show(errorMessageForMessageBox);
this.Close();
}
I would like to close the form parented by the main form or I want the program just do nothing. Now The messageBox ("Game saved succeddfully.") pops up after an error message because it is written under the void calling the errorMessage event. With Exception and braces I could separate the different derivations.
Thank you for help,

Related

WPF forms crashed

Is there any way to catch the crashed form and reopen it again.
public static void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
}
Setting e.Handler to true should prevent the app from shutting down. You will then have to write some code to bring the window up again. There is no "reopen the crashed form" switch I am afraid. There is not even any notion of a "crashed form" as far as the event handler is concerned.
Please also note that keeping an application running like this will leave it in an undefined state. What you really should do is to catch the exception where it occurs and then use the Dispatcher_UnhandledException event handler as a last resort for logging any unhandled exception, perhaps displaying a user friendly message and finally shutting the application down.

C# where does execution come after the handling the event?

Consider i have a "Form" and it contains Button. I started the compiling process (Ctrl +F5). When i click the button the event is occurs and event handler is executed. Where does execution come back after event is handled?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//some Code
}
}
Short Answer: It goes back to listening for more events.
Detailed Answer:
Under the hood, everything in Windows runs on top of the Win32 API. The Win32 API has at least 2 functions that all programs run. The window procedure is one and that is where our event messages get processed. The other one is called the message loop and it looks similar to this:
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
The message loop is the heart of all event-based Windows programs. GetMessage() gets a message from your application's message queue. Any time the user moves the mouse, types on the keyboard, clicks on your window's menu, or does any number of other things, messages are generated by the system and entered into your program's message queue. By calling GetMessage() you are requesting the next available message to be removed from the queue and returned to you for processing.
TranslateMessage() does some additional processing on keyboard events. Finally DispatchMessage() sends the message out to the window that the message was sent to.
In every winforms application is "hidden" main message loop.
Main message loop is basicaly while(true) ... loop and checks for input (and some other) events like Click, KeyDown, etc...
This main loop is executed inside Application.Run(...) is call. Probably in your Program.cs file.
Check the Events overview for Windows Forms
When an event is recorded by the application, the control raises the event by invoking the delegate for that event. The delegate in turn calls the bound method. In the most common case (a multicast delegate) the delegate calls each bound method in the invocation list in turn, which provides a one-to-many notification. This strategy means that the control does not need to maintain a list of target objects for event notification—the delegate handles all registration and notification.
So the control itself, calls the delegate. The code of the control raised the method. So when you click the control there is some code in the control that calls the delegate you have provided.
The code commonly calls the delegate as it would any other function and continuous it's code flow:
i.e.
// do something
deletat(...);
// continue doing something
You can find an even better example here: Understanding events and event handlers in C#
on how delegates are being called.

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.

Cannot access a disposed object

My program has multiple forms. The fifth and final form has a button that when clicked closes the application using the method Application.Exit(). However every time I click the button I receive the error 'cannot access a disposed object' surrounding this code on my first form:
frm2 f2 = new frm2();
this.Hide();
f2.ShowDialog();
this.Show();
The compiler indicates that the statement this.show() is the problem. Could someone explain why I am receiving this error and how to fix it?
Ok edited my answer, I reproduced your issue. If you want to use Form.ShowDialog then you should set the DialogResult of the control that is closing the application. So in the buttons properties you should set the dialog result to something, for example Cancel.
Then on the buttons click event you would do something like this:
private void btnClose_Click(object sender, EventArgs e)
{
if (this.DialogResult == DialogResult.Cancel)
{
Application.Exit();
}
}
Otherwise if you don't need to use Form.ShowDialog, you can just show Form2. The above does not produce the error in my testing.
In your code example, did frm2 make a call to Application.Exit? If it did, then why are you trying to call this.Show again?
Anyway, you may have a problem related to how you started the application's message loop. Are you running Application.Run(), or Application.Run(form1)?
If you provided a form to Application.Run() when you started your message loop, then you should not be calling Application.Exit in order to exit the application. Instead, you should simply close your main window, that would cause the message loop to finish, the call to Application.Run to return, and your application will terminate cleanly.

WinForms: Open a messagebox from the WndProc method (Form class)

I imagined that WndProc is called on another thread rather than main UI thread.
I was right, so I thought that simply using InvokeRequired and Invoke on the form was enough to show a messagebox on the UI thread.
I was wrong. And I don't understand why.
How can I go around this problem?I'm looked around google but didn't find a solution.
What I'm trying to do is simply raising a custom event (ClipboardUpdate) when clipboard changes
the messagebox was just a test but didn't work, while just changing something like a string (a private field of the form) works, but it's not a good thing this behaviour because is a cross-thread operation in an unsafe way.
Update 1:
I don't have the code here because I created it on a friend's computer, however I can explain exactly what I wrote Because is short.
I created a basic winform with visual studio, without anything.
I used AddClipboardFormatListener (interop, but it's quite easy as a function, return int and accept IntPtr) function (on a windows 7 OS) to just detect WM_CLIPBOARDUPDATE message, inside winproc (a simple if, *if (e.Msg == ClipboardExtension.WM_CLIPBOARDUPDATE) DoClipboardUpdate();*).
Now the DoClipboardUpdate do this:
if (InvokeRequired)
Invoke(new VoidDelegate(OnClipboardUpdate));//Void delegate it's a delegate that doesn't take
// Params and returns void
else
OnClipboardUpdate();
Quite easy right? OnClipboardUpdate just do this:
if (ClipboardUpdate != null) ClipboardUpdate(null,EventArgs.Empty);
ClipboardUpdate is an event declared in this way:
public event EventHandler<EventArgs> ClipboardUpdate;
In the end, the only method subscrived to ClipboardUpdate event has this inside:
MessageBox.Show("test");
What happens when I run the code? The event is triggered (I tried with an exception and it works) and the messagebox doesn't popup, however I can't interact anymore with my form because it behaves as if a popup was opened (this is the "normal" behaviour when you open a popup on a different thread, that's why I said that).
Any suggestion on how to solve this?
I didn't understand why it happens but I created a new project and opening a messagebox from WndProc works fine, maybe some thread corrupted main thread memory, I don't know this but as others stated wndproc is the ui thread and should work

Categories