I have a code like this in VS 2012:
private void Form1_Load(object sender, EventArgs e)
{
if (Properties.Settings.Default["Database"] != null)
{
MessageBox.Show("We landed on spot 1");
}
else
{
MessageBox.Show("We landed on spot 2");
}
}
I'm pretty sure I messed up the condition syntax, but I would expect that one of these would happen:
Compiler warns about errors/project fails to run.
First message is shown
Second message is shown.
But neither of these actually happens. I've been staring at this for an hour and resources I could find are pretty slim.
If anyone with an experience could explain me what actually happens here?
Edit:
Thanks to JMK's link I found out this is basically a wontfix bug popping up in VS debugger under Windows x64. Error fires if application is run outside of debugger.
Its silently erroring.
try
{
if (Properties.Settings.Default["Database"] != null)
{
MessageBox.Show("We landed on spot 1");
}
else
{
MessageBox.Show("We landed on spot 2");
}
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
Comes back with "The settings property 'Database' was not found"
Try adding your project namespace before the Properties
if (WindowsFormsApplication2.Properties.Settings.Default.Database != null)
Propably an exception is thrown and not noticed by the debugger.
This happens for Windows Forms projects on 64bit Windows Versions (and is not a behaviour specific to .NET but to Windows in general).
More details here: Visual Studio does not break at exceptions in Form_Load Event
Try pressing STRG + ALT + E and mark the checkbox "Thrown" for "Common Language Runtime Exceptions".
Now the debugger will break on any exception in Form_Load()
Since I know about that my workaround is to completly avoid using the Load event.
Most of my Forms are Dialogs so I shadow the ShowDialog() method and call a Init() function.
public class Form1
{
public new DialogResult ShowDialog()
{
Init();
return base.ShowDialog();
}
public new DialogResult ShowDialog(IWin32Window owner)
{
Init();
return base.ShowDialog(owner);
}
public void Init()
{
// code goes here
}
}
Related
I am trying to create a MessageBox that appears at the start of my program, asking the user if they would like to load a file or not. So far I have:
public static void LoadFile(object sender, FormClosingEventArgs e)
{
System.Windows.MessageBox.Show("Would you like to load a file?",
System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxQuestion);
if (result == DialogResult.No)
{
// cancel the closure of the form.
e.Cancel = true;
}
}
I realize that some of this code is used to exit out of the program. I don't intend to do this, it is just currently still left in from the sample code I was trying. When I try this code, I receive several errors, the major one involves the MessageBoxQuestion. The error reads
The type or namespace name 'MessageBoxQuestion' does not exist in the namespace System.Windows
I previously had this error on the MessageBoxButtons but fixed it by changing it to MessageBoxButton. Starting with just a simple message box, I originally had the code:
public static void LoadFile()
{
System.Windows.MessageBox.Show("Text");
}
This worked perfectly fine, despite the fact that I had to add the System.Windows. to remove the error
The name MessageBox does not exist in the current context.
Does anyone know a solution as to how I can get my MessageBox working correctly?
The WPF version of MessageBox differs from the Windows Forms' version. You need to use this overload.
Here is what I finally came up with:
public static void LoadFile()
{
// Configure message box
string message = "Would you like to load a file?";
string caption = "Startup";
System.Windows.MessageBoxButton buttons = System.Windows.MessageBoxButton.YesNo;
System.Windows.MessageBoxImage icon = System.Windows.MessageBoxImage.Information;
// Show message box
System.Windows.MessageBoxResult result =
System.Windows.MessageBox.Show(message, caption, buttons, icon);
if(result == System.Windows.MessageBoxResult.Yes)
{
}
else if(result == System.Windows.MessageBoxResult.No)
{
}
}
I included the if else branch that I planned to use later.
I have run into an issue that has thrown me for a loop since last night. I decided that in order for my program to be as user friendly as possible, I should do some exception handling so a user would know why it isn't working. However, No matter how I tried to catch the System.Argument Exception, it still would be thrown. I'm not looking for someone to just give me some code to fix this, I would really like someone to explain why this is happening so I know what to do to handle this sort of problem in the future.
using System.Speech.Synthesis;
namespace SpeechProject
{
/// <summary>
/// Interaction logic for EnglishChinese.xaml
/// </summary>
public partial class EnglishChinese : Page
{
public EnglishChinese()
{
InitializeComponent();
}
private void speakBtn_Click(object sender, RoutedEventArgs e)
{
SpeechSynthesizer synth = new SpeechSynthesizer();
try
{
synth.SelectVoice("Microsoft Hanhan Desktop");
synth.Speak(spokenWords.Text);
}
catch (ArgumentException)
{
MessageBox.Show("You need to install the China Chinese Simplified Language Pack to use this feature");
}
}
}
}
I then tried a different approach from this one. I tried an if else combination. Although, i'm pretty sure i'm not doing something correctly with that said if statement. But it does however work for using "Microsoft Zira Desktop" but does not work for the others.
public partial class EnglishChinese : Page
{
public EnglishChinese()
{
InitializeComponent();
}
private void speakBtn_Click(object sender, RoutedEventArgs e)
{
SpeechSynthesizer synth = new SpeechSynthesizer();
if (synth.Voice.Name == "Microsoft Huihui Desktop")
{
synth.SelectVoice("Microsoft Huihui Desktop");
synth.Speak(spokenWords.Text);
}
else
{
MessageBox.Show("You need to install the China Chinese Simplified Language Pack to use this feature");
}
}
}
}
// It automatically throws the message box, when I click the button
This is rather confusing since if it works for one, it should work for all, but that isn't the case with this if statement structure. Any tips would be very much appreciated.
Results with the catch Exception ex and Argument Exception ext:
Stewart_R, Psudonym and EBrown all helped answer this question.
Debug settings needed to be changed to reflect how I wanted certain exceptions to be handled. And the Try Catch method was the better method to use instead of the If Else statements. I had to make sure I caught the specific exception I wanted, in this case it was ArgumentException.
Thank you guys for your help. I really appreciate it.
Background:
A WinForms app, originally written in .NET 1.1 migrated via Visual
Studio to .NET 4.0. Typical menu bar at the top of main app form (NB:
not migrated to ToolStripMenuItem), as you might expect there is a
File menuitem that contains an Exit menu item.
I have implemented Ctrl-L shortcut which will bring up a modal lock
form. I also have a timer component on the main form which will
automatically bring up the lock form if there's no activity for
configurable amount of time.
When the lock form is shown you can either unlock (requiring user to
login again) or quit. If you choose to quit then my code does a
fileExitMenuItem.PerformClick() call.
Problem:
For some strange reason after the migration if I quit from the lock
form which was displayed either automatically or due to Ctrl-L
shortcut then I get a NullReferenceException thrown on the
fileExitMenuItem.PerformClick() line of code.
fileExitMenuItem is not null; with break-when-exception-thrown
switched on I can browse all of fileExitMenuItems properties.
I can break in the designer code of the form and watch the click event
handler being attached. If I use the File >> Exit menu item directly I
can break on the code in the event handler.
So this is a total WTF moment. Any suggestions on what to look at will be greatly appreciated
[UPDATE 1] As requested here is some code - this method is called whenever the user presses Ctrl-L or the lock timer elapses:
private void LockApplication()
{
try
{
// Stop the timer so we don't get any more elapsed events whilst we are waiting
// for a user to respond to the lockdown dialog. In addition stop the callout reminder
// time as once we have locked we don't want that doing it's thing.
lockdownTimer.Stop();
calloutsReminderTimer.Stop();
// Clone the current identity so we can check it later.
var previousIdentity = (CudosIdentity)BOUtilities.CurrentIdentity.Clone();
// Show lockdown form.
System.Windows.Forms.DialogResult result;
using (var lockForm = new Forms.applicationLockedForm())
result = lockForm.ShowDialog(this);
if (result == DialogResult.OK)
{
// Did we unlock with a different login?
if (!previousIdentity.Equals(BOUtilities.CurrentIdentity))
{
// Yes, so lose all changes.
CloseOpenForms();
if (_currentLoadSpec != null)
_currentLoadSpec.CancelContent();
}
RefreshLockTimerSetting(null);
}
else
fileExitMenuItem.PerformClick();
}
catch (Exception ex)
{
Helper.LogError(ex);
}
finally
{
lockdownTimer.Start();
calloutsReminderTimer.Start();
}
}
This is the code for the exit menu item:
private void fileExitMenuItem_Click(object sender, System.EventArgs e)
{
Application.Exit();
}
When the following line in LockApplication method from above is called I get the NullReferenceException:
fileExitMenuItem.PerformClick();
[UPDATE 2] Call stack info when the above line is executed:
[External Code]
Cudos.exe!Cudos.mainForm.LockApplication() Line 1132 + 0x10 bytes C#
Cudos.exe!Cudos.mainForm.fileLockCudosMenuItem_Click(object sender, System.EventArgs e) Line 1594 + 0x8 bytes C#
[External Code]
Cudos.exe!Cudos.mainForm.Main() Line 1880 + 0x1d bytes C#
[External Code]
I am not sure, but I will try to remove the restart of the timers if you call the Perform_Click.
The Tick event could be called when there is no more the application because you call Application.Exit().
private void LockApplication()
{
try
{
lockdownTimer.Stop();
calloutsReminderTimer.Stop();
.....
if (result == DialogResult.OK)
{
......
lockdownTimer.Start();
calloutsReminderTimer.Start();
}
else
fileExitMenuItem.PerformClick();
}
catch (Exception ex)
{
Helper.LogError(ex);
lockdownTimer.Start();
calloutsReminderTimer.Start();
}
// remove the finally clause
}
In the end I gave up and just hacked it by changing the fileExitMenuItem.PerformClick() to Application.Exit(). So I still don't have any idea why it was throwing the exception but it at least now works. I guess if I put more logic into the fileExitMenuItem click handler I will just have to remember to extract it into a method and update this hack to call that method to.
After 2+ hours of looking WHY my bloody process would not exit when I closed the window. I finaly found out that it was the problem in the main window(and not in a thread, because that could have been also the problem)! But I still got NO idea why it bugs.
So THIS code makes it bug:
private void Window_Closing(object sender, CancelEventArgs e)
{
try
{
MessageBox.Show(e.Cancel.ToString()); // False always
if (formcontroler.formchampinfo != null) // THIS IS NULL so it won t go into this IF
{
formcontroler.formchampinfo.Close(); // never gets here so it doesn t matter what this do right ?
}
MessageBox.Show(e.Cancel.ToString()); // always false, just to check or it would get to this part tbh
}
catch (Exception ex)
{
throw (ex); // never gets thrown
}
}
WHICH IS REALY Strange (to me)! because it gets to the 2nd messagebox and the e.cancel = FALSE so it should not cancel it and just shutdown and the process should get killed(and Visual studio should stop debugging).
Anyway it doesn t stop. It just keeps the process alife and I got no clue why, If I remove the middle if or replace it with a simpler one like:
private void Window_Closing(object sender, CancelEventArgs e)
{
try
{
MessageBox.Show(e.Cancel.ToString()); // False always
if (true == true) // just To test ofc
{
int lol = 5;
lol++;
}
MessageBox.Show(e.Cancel.ToString()); // always false, just to check or it would get to this part tbh
}
catch (Exception ex)
{
throw (ex); // never gets thrown
}
}
then it works and the program exits like it should(the process is killed and Visual studio stops debugging.
Some side code that shoudn t mattter I think
class formcontroler
{
public static frmchampinfo formchampinfo;
}
The frmchampinfo is a window, but atm I loaded it or declaterded it (like formchampinfo = new frmchaminfo();)
Is this a bug or what happened here ? I realy don t get why it doesn t shutdown totaly at my code.
SOLVED sorry I can t answer it until 7 hours but then I am asleep.(Because I don t got 100 rep yet)
Oke so after looking deeper and deeper I found out that the IF statement creates an other form in my formcontroller class(sorry I didn t provide full code in answer so you coudn t figure it out):
class formcontroler
{
public static frmchampinfo formchampinfo;
public static Window activeform;
public static frmlog formlog = new frmlog();
//... more code blabla
}
The formlog "gets made" here. If I add formcontroller.formlog.close() to the code then it can close completly.
private void Window_Closing(object sender, CancelEventArgs e)
{
try
{
MessageBox.Show(e.Cancel.ToString()); // False always
if (formcontroler.formchampinfo != null) // THIS IS NULL so it won t go into this IF
{
formcontroler.formchampinfo.Close(); // never gets here so it doesn t matter what this do right ?
}
formcontroler.formlog.Close(); // THIS FIXED IT... lame sorry for all your time. HoweveR I have learned something hope you did too.
MessageBox.Show(e.Cancel.ToString()); // always false, just to check or it would get to this part tbh
}
catch (Exception ex)
{
throw (ex); // never gets thrown
}
}
Check if the ShutdownMode of your App class is set to OnMainWindowClose.
You can also explicitly shutdown the application by:
Application.Current.Shutdown();
I'm in the middle of adding new functionality to my winforms controls, and part of that requires that a variable that was once always used to now be optional (if it's null, get the data from a second source). I made some changes and ran my form, only to find out nothing was happening, even functionality that previously worked. Confused I stepped through the code and found out that my Winforms user control was throwing a NullReferenceException when it encountered my variable, but in the UI no errors were being thrown.
My setup is I have a UserControl with a combo box. When the user changes that combo box it loads a secondary UserControl in a panel the first control has. The second control is what is throwing the exception.
Here are the code paths:
private void cmbActionType_SelectedIndexChanged(object sender, EventArgs e)
{
if (_loading)
return;
// ActionType was changed, update the action.ActionType value
if (cmbActionType.SelectedItem != null)
{
if (cmbActionType.SelectedItem.ToString() == SETVALUE_OPTION)
_action.ActionType = ActionTypes.SetValue;
else if (cmbActionType.SelectedItem.ToString() == CHECKVALUE_OPTION)
_action.ActionType = ActionTypes.CheckValue;
else
_action.ActionType = ActionTypes.CustomAction;
}
RefreshActionPanel();
_editor.DataModified();
}
private void RefreshActionPanel()
{
// Control defaults
AnchorStyles styles = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
UserControl subControl = null;
// Clear the currently active control
pnlActionDetails.Controls.Clear();
// Determine what type of control to load in the panel
if (cmbActionType.SelectedItem != null && cmbCaseType.SelectedItem != null)
{
// SetValue or CheckValue actions
if (cmbActionType.SelectedItem.ToString() == CHECKVALUE_OPTION || cmbActionType.SelectedItem.ToString() == SETVALUE_OPTION)
{
if (_caseTypeMap.ContainsKey(cmbCaseType.SelectedItem.ToString()))
subControl = new SetCheckActionControl(_action, _editor, _caseTypeMap[cmbCaseType.SelectedItem.ToString()]);
}
// CustomAction action type
else
{
// Check if the requested case is a type or defined in a script
if (_caseTypeMap.ContainsKey(cmbCaseType.SelectedItem.ToString()))
{
subControl = new CustomActionControl(_action, _editor, _caseTypeMap[cmbCaseType.SelectedItem.ToString()]);
}
else if (_editor.ScriptDefinitions.Any(x => x.CaseName == cmbCaseType.SelectedItem.ToString()))
{
var definitions = _editor.ScriptDefinitions.Where(x => x.CaseName == cmbCaseType.SelectedItem.ToString()).ToList();
subControl = new CustomActionControl(_action, _editor, definitions);
}
}
}
if (subControl != null)
{
subControl.Anchor = styles;
subControl.Height = pnlActionDetails.Height;
subControl.Width = pnlActionDetails.Width;
pnlActionDetails.Controls.Add(subControl);
}
}
public CustomActionControl(TestAction action, fmEditor editor, IList<TcScriptDefinition> scriptDefinitions) : base(action, editor)
{
_loading = true;
InitializeComponent();
_scriptDefinitions = scriptDefinitions;
PopulateActionList();
SetupDataGrid();
_loading = false;
}
private void SetupDataGrid()
{
// Clear the current contents of the datagrid
grdParameters.Rows.Clear();
if (cmbAction.SelectedItem == null)
return;
// Retrieve the action code from the drop down
string actionCode = cmbAction.SelectedValue.ToString();
// Check if any paramters are available for this action
if (!_availableActionParameters.ContainsKey(actionCode))
return;
// Add a new row for each parameter available for this action
foreach (string param in _availableActionParameters[actionCode])
{
string display = param;
// Determine if the parameter has a display string
if (_formInstance.CodeDisplayMap.ContainsCode(param))
display = _formInstance.CodeDisplayMap.GetDisplayStringFromCode(param);
// Create the array for the row, with an empty string as the current value
string[] row = { display, string.Empty };
// Check if the current action uses this action code.
// If so, retrieve the value for this parameter and use it in the row
// Note: Case-INsensitive comparison must be performed here
if (_action.Attributes["action"].Equals(actionCode, StringComparison.CurrentCultureIgnoreCase))
if (_action.Attributes.ContainsKey(param))
row[1] = _action.Attributes[param];
grdParameters.Rows.Add(row);
}
}
The NullReferenceException is coming from the SetupDataGrid() method where _formInstance is being called. However, usually when an application encounters an unhandled exception the JIT system throws an error message saying such (and as you can see, there's no try/catch statements used unless I am blind).
Why does my winforms application show no signs of an exception occurring. I'd rather an unhandled exception message occur rather than nothing happening, as that makes it harder for users to know something critical went wrong (as opposed to it not responding to their commands)
Edit: To clarify since there seems to be some confusion, I do NOT care about breaking on this exception in visual studio when debugging. The fact of the matter is that the application should not be hiding unhandled exceptions, and my application should crash (or rather show the JIT message that an unhandled exception occurred), even when not in debug mode outside of visual studio.
This is not a debug time question but a production run time question. If this code throws an OutOfMemoryException for instance, I need it to not be silently ignored. Right now it is being ignored.
Go to Debug->Exceptions... (Ctrl-D, E if you are using default shortcuts) from your menu bar in Visual Studio and check the box for Thrown under Common Language Runtime Exceptions. This will cause your program to break on exceptions even if they are in a try/catch block. You can then do a step forward and see where the code is jumping to for the next instruction. That should bring you to the catch block that is hiding your exception.
It may be jumping in to .NET code for the catch, you can go to Debug->Options and Settings.. and turn on Enable .NET framework Source Stepping to see what it is jumping in to.
Here is a example of catching the unhandeled execptions in code
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
MessageBox.Show("0");
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("1");
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
throw new ArgumentNullException();
}
}
Click the button and 1 appears, the program should still run afterwards.
However as I said in my last comment, check that user-unhandeled is checked (maybe uncheck and recheck) in Debug->Exceptions first it may solve your initial issue..
They can be caught if you have a try/catch in your Main, or if you have a ThreadException handler. Also check out SetUnhandledExceptionMode.
Note that if they're caught in Main, your program will just exit silently. ThreadException can "catch" and ignore them.
EDIT: Since the debugger doesn't break when you uncheck the box for Thrown under Common Language Runtime Exceptions, it's being caught by the code for Windows Forms. This is not ideal, but a lot of the BCL does this. You don't need to worry about it catching OutOfMemoryException or anything like that; the BCL should only be catching exceptions that it expects (vexing exceptions).
To be clear, the exception is not "unhandled". It is handled by the BCL code.