C# multiple button with similar behavior - c#

I am new to C# and I am following this C# tutorial at the moment. In this tutorial I came across the exercise to develop a calculator.
A C# .Net Calculator - Design Stage
In the solution given in the exercise, each digit button was given a btn*_click method which can be generalized pretty easily.
(source: homeandlearn.co.uk)
How can we write the code, so that we can generalize these 10 functions? I though it can be done by modifying initializeComponent(), but comment about it says it should not be modified using code editor.
How can this problem be tackled.

You can tie all buttons to the same click event handler, and use sender to get the text:
private void btnAnyButton_Click(object sender, EventArgs e)
{
Button theButton = sender as Button;
txtDisplay.Text += theButton.Text;
}

The tutorial you posted is using the visual editor in visual studios. By default the designer will generate code with the convention {controlname}_{eventname} you can explicitly assign a different event name in the properties window, and all the buttons could share the same event method.
And then it looks like you could refactor this like:
private void btn_click(object sender, EventArgs e)
{
Button btn = sender as Button;
if(btn != null)
txtDisplay.Text += btn.Text;
}
I hope that helps.

You could generate these buttons dynamically from the code and assign them some value in the tag attribute. From there, you can hook them all up to the same event handler (we're talking about the number buttons, as in 0,1,2,3,4...). In the onClick event handler you would get the tag value of the caller and do what you have to do.
Pseudocode:
void onClick(Button caller){
int btnNb = (int) caller.Tag;
//do what you have to do
}
The tag attribute is not necessary but I find it cleaner than getting the button text and converting to an int.

Related

Textbox_Enter event not does nothing

I want to be able to tell when the user cliked on a textbox and is in "edit" mode. Everywhere I look I see the textbox_Enter and textbox_Leave events being used with the instructions within that and it works fine. For me however it doesn't do anything. I tried elimination as many outside factors as possible, including creating a brand new project just for testing purposes and copied some code samples yet again nothing happens when I click on the textbox. I'm using Visual Studio 2017 on Windows 10 with Visual C# Application Windows Form (.NET Framework)
Also here's a sample of the code I try to use if it helps for whatever reason
private void textbox_Enter(object sender, ControlEventArgs e)
{
label.Text = "ok";
}
First of all the type of the e parameter is not correct: It must be EventArgs, not ControlEventArgs:
private void textbox_Enter(object sender, EventArgs e)
{
// Do something
}
Second, you need to register the event in the forms designer with the textbox control in the properties window:
You need to wire up this method to the textbox enter event. Select the control and then look at the events section in the properties tab.

I want make all textboxes on my form to accept only numbers with as little code as possible - c#

I am making a relatively simple bit of software which has quite a few textboxes and i want a way to only allow numbers in all textboxes in the form with hopefully one piece of code. I am currently using the following code to only allow numbers for one textbox but it means repeating those lines for each textbox.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
The textboxes are also inside a panel incase that makes a difference.
Create a derrived DigitsOnlyTextBox, with the method implemented, and use it in place of TextBoxes.
As Darek said, one viable option is to:
Create a derrived DigitsOnlyTextBox, with the method implemented, and use it in place of TextBoxes
A second option is to simply point each TextBox to the same event handler. For example, in the Form.Designer.cs:
this.textBox1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBoxNumericOnly_KeyPress);
this.textBox2.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBoxNumericOnly_KeyPress);
this.textBox3.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBoxNumericOnly_KeyPress);
...
Then your handler:
private void textBoxNumericOnly_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
Assuming you're using Visual Studios and you've already created the event handler the first time (for textBox1), you can easily do this all in the designer view of the Form:
A Default Handler
Copy Def Handler
If you're using Windows Forms and not WPF you can use a MaskedTextBox.
Not sure if you can replicate the capability in WPF, having never used it.

TextChanged event doesn't work.

I have a textbox in Form and i want to detect when the text has changed but the code I have found is giving me no joy.
I am probably missing something in the proporties or something you have to define before.
Here is my code:
private void tbxparkingTimesS1_TextChanged(Object sender, EventArgs e)
{
MessageBox.Show("You are in the ToolStripItem.TextChanged event.");
}
Thanks for any help with this trivial problem.
To wire the TextChanged event to a particular method inside your code do the following
Click on the TextBox inside your form
Open the properties windows (press F4 or menu View -> Property Window )
Select the event page (lightning icon)
Double click on the TextChanged property line
Insert your code inside the template build for you by Visual Studio
Have you assigned the event handler to the textbox?
Normally this will be done "behind the scenes" by Visual Studio - with the result being an additional line of code in your .designer file.
Something like:
this.tbxparkingTimesS1.TextChanged += new System.EventHandler(tbxparkingTimesS1_TextChanged);
(It['s been a while since I've done webforms - so that might be slightly off)
Double Click on Text box it will generate text change event for you.
private void tbxparkingTimesS1_TextChanged(object sender, EventArgs e)
{
// implement your code here.
}
When you double click VS will create event handler in your designer.cs file as bellow
this.tbxparkingTimesS1.TextChanged += new System.EventHandler(this.tbxparkingTimesS1_TextChanged);
You can do the same by using property window events or create event on code behind.

Check for Button Click Event on Form - C#

I currently have a form with about 13 buttons on it.
I want to be able to perform a function when one of those buttons are clicked. But I am trying to keep from having 13 different button click events.
Is there some way for me to be able to determine when any button click event is fired, and be able to tell which button fired it?
Thanks!
Have one function that handles all of the click events and use the properties of the 'sender' object to identify the specific button.
You can have different button click handlers, and name them according to button actions, also you can have single event handler for all of them, in this case parameter sender can be cast to button and for example by it's name, finding related button.
But I offer if you have similar behavior on group of buttons map them to a single function, but if actions are different using different method is better, but in all one form with 13 button is not good, you can change them to menu, Tab, ...
foreach (Control ctl in this.Controls)
{
if (ctl is Button)
(ctl as Button).Click += MyButtonHandler;
}
protected void MyButtonHandler(object sender, EventArgs e)
{
Button clickedButton = sender as Button;
//...
}
The first parameter to the callback function is the button that was pressed.
private void OnButtonClicked(object sender, EventArgs e){
Button oButton = sender as Button;
if (oButton != null){
// your logic goes here !
}
}
oButton variables is your current button. (important to check if oButton != null when using as operator)
on the click event you get a reference to the Sender - this is the clicked button so inside that you could test for the Content or Tag and act based on the value:
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show((sender as Button).Tag.ToString());
}
I think that in this situation using delgates would be proper. Check these links out for further information on implementation.
The C# Station Tutorial: Introduction to Delegates and Events
Delegates and Events in C# / .NET
Every proper eventhandler has an Object sender parameter. Give all 13 buttons the same handler by typing the same name in the Properties window OnClick event, for instance: OnAnyButtonClicked. The created function will be:
private void OnAnyButtonClicked(object sender, ...)
{
// sender is the button that was clicked,
// find out which button is clicked
// call the corresponding function
}
Tip:
To find out which button is pressed you could use Object.ReferenceEquals
A faster way to avoid if ... then ... else if ... then ... else if...
is using the Tag property of each Button.
Give eacht Button.Tag an enum value corresponding to the action that has to be performed and use a switch statement to find out what has to be done.
You could also assing a delegate to the button.Tag, but that is almost the same as making a different onClick event handler for every button.

How can I give focus to a textBox after a Tab has been selected?

I'd like give focus to a textBox after a Tab has been selected but no matter what I try it doesn't work. I've looked at similar questions here but they don't get me the results I need. Here is what Ive tried.
private void tabBDERip_Click(object sender, EventArgs e)
{
textBoxPassword.Focus();
}
and
private void tabAll_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabAll.SelectedTab == tabBDERip)
{
textBoxPassword.Focus();
}
}
Can someone please tell me what I'm doing wrong?
Thanks
First thing the Click event of the TabPage control fires when the user clicks inside the TabPage not on the header so your SelectedIndexChanged event is the one you want to use.
I just tested code very similiar to yours:
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.SelectedTab == tabPage2)
{
textBox4.Focus();
}
}
And it worked fine.
Is the password textbox not enabled or something like that?
If you try to call Focus() on a different control does that also not work?
If you set a breakpoint inside the SelectedIndexChanged code does it get hit?
Update: Interesting. If the breakpoint isn't getting hit (before the if) I would double check that your eventhandler is properly attached. Look in your designer.cs for something like:
this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged);
Update: I put my working example at http://www.ccswe.com/temp/SO_TextBoxFocus.zip maybe looking at it will help you figure out where the issue is.
Update: The easier way to attach an event handler to a control on your form:
1: Select the Control to want to attach an event handler to and then click the Events icon (lightning bolt) in the Properties window.
alt text http://www.ccswe.com/temp/Attach_EventHandler_1.png
2: Find the event you want to attach to and double click to the right.
alt text http://www.ccswe.com/temp/Attach_EventHandler_2.png
3: A code stub will be automatically generated for you and the event will be attached in the designer.
alt text http://www.ccswe.com/temp/Attach_EventHandler_3.png
If you look at the properties window again you'll now see the name of the method that was generated.

Categories

Resources