Nothing in Textbox with Exception Handling in C# - c#

I have a windows Form and i'm using C# for this program. In my form i have a button and a textbox.
I want to click on the button and delete the numbers/letters by incorporating a custom exception (for learning purposes), but i keep on getting an error.
The error in my program is when there is nothing in the textbox, and if i click on the delete button the program crashes. Can someone help me out with this?
public class deleteData : Exception
{
public deleteData()
: base("") { }
}
private void btn_Delete(object sender, EventArgs e)
{
if (textbox1.Text != null)
{
textbox1.Text = textbox1.Text.Remove(textbox1.Text.Length - 1, 1);
}
else
{
throw new deleteData();
}
}

I modified your program a bit. Give it a try and see if this is what you had in mind. The custom exception pops up a messageBox as its exception handling, and the catch block puts the stack trace in the textBox. You could use either, both, or neither method for handling the exception. The main thing is that as long as the exception occurs in the Try-Catch block and is handled in some way there, you will not crash your program. It handles the exception and keeps on running.
You would not usually do this, but I can see the educational benefit in it.
using System;
using System.Windows.Forms;
namespace TryCatch
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn_Delete_Click(object sender, EventArgs e)
{
try
{
if (textBox1.Text != "")
{
textBox1.Text = "";
}
else
{
throw new deleteData("Here we are having the custom exception do its own exception handling");
}
}
catch (Exception ex)
{
textBox1.Text = "Here we are catching the custom exception in a catch block\r\n\r\n";
textBox1.Text += "Exception details:" + ex.StackTrace.ToString();
}
}
public class deleteData : Exception
{
public deleteData(string s)
{
MessageBox.Show(s);
}
}
}
}

As many people suggested, this is not a good idea, but if you insist, I'll explain how to do this.
You want to check whether text in a text box is null. If it is, then throw an exception. However, I think you misunderstand what it means by "a string is null" and "a string is empty". An empty string is "" and a null string is just null, nothing. A null string cant do anything, if you call its methods, NullRefereneException! But you can call methods from an empty string.Normally the text in text boxes is empty when you see an empty text box. I guess you want to check for that.
if (textbox1.Text != "") {
textbox1.Text = ""; // This is to remove the text, as you said in the question
} else {
throw new deleteData ();
}

Related

C# Program Crash comboBox SelectedItem ToString

I have no idea, why my program crash.
If i click "Reload" Button:
private void reloadBtn_Click(object sender, RoutedEventArgs e)
{
comboFilter.Items.Clear();
dataGridPrivatecustomers.Columns.Clear();
dataGridPrivatecustomers.ItemsSource = null;
load_columns_privatecustomer();
load_values_privatecustomer();
}
All works.
But if I select a filter for my search function and click reload, then it crashes:
private void comboFilter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
labelfilter.Content = "Filter: " + comboFilter.SelectedItem;
filtervalue = comboFilter.SelectedItem.ToString();
}
This is the breakpoint:
filtervalue = comboFilter.SelectedItem.ToString();
And I get a NulLReferenceException Error.
I tryed to make a filtervalue = null; in reloadBtn_Click but also doesn't work.
The comboFilter_SelectionChanged is somehow fired after the reload where you remove items from the combo, which is result of clear method. Make sure you have SelectedItem not null in comboFilter_SelectionChanged before you use it.
private void comboFilter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if( comboFilter.SelectedItem != null)
{
labelfilter.Content = "Filter: " + comboFilter.SelectedItem;
filtervalue = comboFilter.SelectedItem.ToString();
}
}
As a additional note your program must not crash by not catching the exception being thrown in your program. Use try-catch to properly handle the exception. And also try to avoid them before they could occur. Like we did here by checking for null. This will prevent program crashing.
try-catch (C# Reference) - Why program would crash (stop execution)
When an exception is thrown, the common language runtime (CLR) looks
for the catch statement that handles this exception. If the currently
executing method does not contain such a catch block, the CLR looks at
the method that called the current method, and so on up the call
stack. If no catch block is found, then the CLR displays an unhandled
exception message to the user and stops execution of the program.
The exception gets thrown because comboFilter_SelectionChanged is called implicitly from reloadBtn_Click when comboFilter.Items.Clear() is called. In this case comboFilter.SelectedItem changes from the previously selected item to null.
Check for null in comboFilter_SelectionChanged:
private void comboFilter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (comboFilter.SelectedItem != null)
{
labelfilter.Content = "Filter: " + comboFilter.SelectedItem;
filtervalue = comboFilter.SelectedItem.ToString();
}
}
You may want to add a null-check for comboFilter.SelectedItem, e.g. like comboFilter.SelectedItem?.ToString()

Where to declare variables in C#

I have created a simple calculator using VS 2013 Pro... and here is the segment of the codes:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CalcTwo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string input = string.Empty;
double numb1, numb2, result;
private void button1_Click(object sender, EventArgs e)
{
double.TryParse(textBox1.Text, out numb1);
double.TryParse(textBox2.Text, out numb2);
result = numb1 + numb2;
textBox3.Text = result.ToString();
}
private void button4_Click(object sender, EventArgs e)
{
double.TryParse(textBox1.Text, out numb1);
double.TryParse(textBox2.Text, out numb2);
result = numb1 - numb2;
textBox3.Text = result.ToString();
}
}
}
now the problem I'm facing is, I've got two more buttons for multiplying and dividing, which in turn forces me to copy paste
double.TryParse(textBox1.Text, out numb1);
double.TryParse(textBox2.Text, out numb2);
for each button. I tried to put the codes with the other variables(double numb1, numb2, result) but getting an error...
Here is the screenshots
Pretty new to Visual Studio and C#.
Help is appreciated! :)
The declaration of the variables is fine at the class level. However, in order to reduce the code duplication you can extract that specific functionality into its own method. Something like this perhaps:
private void CaptureValues()
{
double.TryParse(textBox1.Text, out numb1);
double.TryParse(textBox2.Text, out numb2);
}
Then in the handlers:
private void button1_Click(object sender, EventArgs e)
{
CaptureValues();
result = numb1 + numb2;
textBox3.Text = result.ToString();
}
This gives you a convenient place to put additional code. Checking the inputs and displaying a message, for example:
private void CaptureValues()
{
if (!double.TryParse(textBox1.Text, out numb1))
// textBox1 couldn't be parsed, show an error message
if (!double.TryParse(textBox2.Text, out numb2))
// textBox2 couldn't be parsed, show an error message
}
You could even go a step further and put the values into class-level properties. Something like this:
private double Value1
{
get
{
double result;
if (!double.TryParse(textBox1.Text, out result))
throw new Exception("Couldn't parse the first text box!");
return result;
}
}
private double Value2
{
get
{
double result;
if (!double.TryParse(textBox2.Text, out result))
throw new Exception("Couldn't parse the second text box!");
return result;
}
}
With those, you don't need your numb1 or numb2 variables at all, just reference the properties directly:
textBox3.Text = (Value1 + Value2).ToString();
Currently the properties can throw exceptions, so you might want to handle that:
try
{
textBox3.Text = (Value1 + Value2).ToString();
}
catch (Exception ex)
{
// examine what happened with ex and show an error
}
You can throw a more specific Exception type of course, even a custom one. Or you can respond to the error in the properties instead of in the handlers and not use exceptions at all. (There's an argument to be made, and I agree with it, never to use exceptions for normal logic, and this is potentially one of those edge cases. If it's normal logic, don't use exceptions. If it's an exceptional case and the value should never be un-parseable, go ahead and use them. I'd prefer not to in this case, but was just adding it as a possibility.)
There are a lot of options.

Encapsulating a control inside an exception

Relatively new to C#/.NET/GUI programming, but here goes. Right now I'm writing a business application at work using WinForms. I have about 5 textboxes and 1 combobox that I want to verify if is empty and if so then tell the user and set focus on that control. How should I go about doing this?
I could either have an if statement that checks each control:
if (usernameField IsNullOrEmpty) then:
setFocus(UsernameField);
return;
if (addressField IsNullOrEmpty) then:
setFocus(addressField);
return;
continue with rest of application as normal...
Or I could do this with exceptions:
try {
if (usernameField IsNullOrEmpty) then:
throw new Exception(usernameField);
if (addressField IsNullOrEmpty) then:
throw new Exception(addressField);
} catch (Exception e) {
setFocus(ControlField) // encapsulate in exception some way?
}
Or to prevent code duplication, just write a function:
try {
checkField(usernameField);
checkField(addressField);
} catch (Exception e) {
setFocus(ControlField) // encapsulate in exception some way?
}
void checkField(control ctrl) {
if (ctrl IsEmptyOrNull)
throw new Exception(ctrl);
}
Being relatively new to GUI programming, does a text field being empty deserve an exception or would this be considered normal program flow?
Throwing Exceptions for program flow is not recommended.
Write a helper method.
private bool IsTextboxValid(Textbox ctrl)
{
if(string.IsNullOrEmpty(ctrl.Text))
{
ctrl.Focus();
return false;
}
return true;
}
And to use it:
if(!IsTextboxValid(addressBox)) return;
if(!IsTextboxValid(nameBox)) return;
I would not use an exception, exceptions should be thrown in exceptional situations, user not filling in a field doesn't count. As for actually detecting the empty control and setting focus, there are tons of ways, like simple if checks as you have, to more complicated solutions with binding and validation and all that.

Window closing bug or e.cancel = false but it won t totaly shut down

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();

Control Form from other Classes and other main Problems

I'm not that good in OOP or even C# but I want to try to keep my code as clean as possible.
Lets say we've got something like that within the Namespace "GoogleCalendarNotificator":
public partial class MainForm : Form
{
private object calendarData;
public MainForm()
{
InitializeComponent();
}
private void recieveCalendarDataButton_Click(object sender, EventArgs e)
{
getCalendarDataBW.RunWorkerAsync();
}
private void getCalendarDataBW_DoWork(object sender, DoWorkEventArgs e)
{
try {
getCalendarData getCalendarDataObj = new getCalendarData();
calendarData = getCalendarDataObj.getData();
} catch (Exception err) {
statusHandler("Login Failed, Please check your Data", err.Message);
}
try {
workWithCalendarData workWithCalendarDataObj = new workWithCalendarData();
workWithCalendarDataObj.workWithData(calendarData, MainForm.ActiveForm);
statusHandler("New calendardata recieved");
} catch (Exception err) {
statusHandler("Login Failed, Please check your Data", err.Message);
}
}
public void statusHandler(string displayMessage, string tooltipMessage = null)
{
string curTime = DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString();
statusLabel.Text = curTime + " - " + displayMessage;
if (tooltipMessage != null)
{
statusLabel.ToolTipText = "Original error message: " + tooltipMessage;
}
}
Is this a good solution for ErrorHandling?
And how about this part:
workWithCalendarData workWithCalendarDataObj = new workWithCalendarData();
workWithCalendarDataObj.workWithData(calendarData, MainForm.ActiveForm);
I simply want to give another class (workWithCalendarData) the possibility to interact with the MainForm. But I do not want simply written in the workWithCalendarData class something like:
MainForm hehe = new MainForm();
hehe.DOSOMETHING();
I want it to be dynamicly if anybody knows what I mean. Like give the class the Information needed to work with the Form (a.e. MainForm.ActiveForm).
MainForm hehe = new MainForm();
hehe.DOSOMETHING();
Well, that just doesn't work. It creates a new form, one that isn't visible because Show() wasn't called. You'll need a reference to the existing form, this in the MainForm's code. You can pass it to the worker class by calling its constructor, passing the reference.
That is however a Bad Idea. It makes your worker class dependent on the user interface. Changing the GUI, happens often because it is, well, so visible, will break your worker class. You solve that problem by using events. Let the worker class raise the event when something worthwhile happens. So that the form can then obtain the information from the class object and update the UI accordingly.
Also look into the MVC pattern to get some ideas.
Remember that your form is also a class. Use standard OOP mechanisms for allowing one class to interact with another. Events, Properties, and Methods can all be used.

Categories