Winform copy button text to textbox using universal method - c#

So this is a fairly straightforward thing, and I am just curious if there is a better way to do it to save lines of code. For class we are making a teletype machine. Basically there is a textbox, and a series of buttons A-Z and 0-9. When you click the button it adds the corresponding letter/number to the textbox. When you click send, it adds the contents of the textbox to a label and resets the textbox. Everything works and it only took a few minutes to build. However there is a mess of redundant lines and I was curious if there is a way to clean up the code with a method.
This is my current code.
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = box_UserInput.Text + "A";
}
As you can see, it is very simplistic and straight forward. Click A, and "A" gets added to the textbox. However the Text property of the button is also just "A" and I want to know if there is a way to just copy the text property of that button and add it to the textbox string.
Something like this, except with a universal approach where instead of having to specify btn_A it just inherits which button to copy based on the button clicked. That way I can use the same line of code on every button.
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = box_UserInput.Text + btn_A.Text;
}

You can use this which is more universal as the Control class contains the Text property. Also, using the best practice $"".
private void btn_A_Click(object sender, EventArgs e)
{
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";
}
You can also assign the same event to each button. Create an event, say addControlTextOnClick and assign the same event to each button.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void addControlTextOnClick(object sender, EventArgs e)
{
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";
}
}
You can even shorten this more using this C# construct:
private void addControlTextOnClick(object sender, EventArgs e) =>
box_UserInput.Text = $"{box_UserInput.Text}{((Control)sender).Text}";

Related

Grabbing the textbox label

Hello im making my first project with about 10 different textboxes where the user puts data in. when he/she clicks the the textbox the textbox text clears and a virtual numpad form pops up and when he leaves the textbox the numpad "hides".
right now (or i would) i have 2 events for every textbox, a click event and a leave event,
private void sheetWidthBox_Enter(object sender, EventArgs e)
{
vnumPadForm.Location = PointToScreen(new Point(sheetWidthBox.Right, sheetWidthBox.Top));
vnumPadForm.Show();
}
Im sure there is a way of dynamically coding that in one event and just grabbing the label name. i have played around with it a bit on my numpad like this and it works good;
private void button_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
string num = b.Text;
SendKeys.SendWait(num);
}
Like that but instead i want to get the label name
right now (or i would) i have 2 events for every textbox, a click event and a leave event,
it works but very inefficient.
Change the name of the handler to something generic like "anyBox_Enter()", and update to the code below:
TextBox curTextBox = null;
private void anyBox_Enter(object sender, EventArgs e)
{
curTextBox = sender as TextBox;
vnumPadForm.Location = PointToScreen(new Point(curTextBox.Right, curTextBox.Top));
vnumPadForm.Show();
}
Note that I added a class level variable called "curTextBox" that gets set from the generic handler! This will track whatever TextBox was entered last.
Now, one by one, select each TextBox on your Form that you want to wire up to this common handler. After selecting each one, in the Properties Pane, click on the "Lightning Bolt" Icon to switch to the events for that control if they are not already showing. Find the "Enter" entry and change the dropdown to the right so that it says "anyBox_Enter".
Then in your button click handlers you can use the "curTextBox" variable to know where to send the key:
private void button_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
string num = b.Text;
if (curTextBox != null) {
curTextBox.Text = num; // or possibly APPEND this to the TB?
}
}

Visual Studio C #, Loop

Visual Studio C #
I made a calculator, and now I have to make a calculator memory (event).
There are 4 components other than the calculator: one Textbox for the answer of the calculator, two Buttons for "M" and "M+", and one Lable to display the answer again.
When the user clicks the “M” button, the contents of the Answer TextBox should be copied to a memory variable. Also make it so that when the user moves the mouse over the label, the value in the memory variable will appear in this label, and then disappear, when the mouse moves away from the label. Also add one more button, an “M+” button. When the user clicks this button, the contents of the Results box will be added to Memory. You will need to use a Global Variable to store this data.
My problem is that the label doesn't appear when the mouse over the label, and also it doens't disappear when the mouse leave the label. How can I fix it?
And also, is this way the right way to use the Global variable?
Below is my code (I just put the code for "M" and "M+" buttons, not the code for the calculator).
private String ans;
private Double answer;
private Double answerPlus;
private void btnM_Click(object sender, EventArgs e)
{
ans = txtDisplay.Text;
answer = double.Parse(ans);
lblblank.Text = answer.ToString();
}
private void lblblank_MouseEnter(object sender, EventArgs e)
{
lblblank.Show();
lblblank.Text = answer.ToString();
}
private void lblblank_MouseLeave(object sender, EventArgs e)
{
lblblank.Hide();
}
private void btnMplus_Click(object sender, EventArgs e)
{
answerPlus = answer + double.Parse(ans);
lblblank.Text = answerPlus.ToString();
}
Storing variables
The way you store your values is fine.
Events
Once you call .Hide() the next MouseEnter/MouseLeave-event will not be triggered anymore. What you could do is to take a panel, or any layout element as a wrapper/parent-element for the label and then adjust your event-callbacks to something like that:
private void panel_MouseEnter(object sender, EventArgs e)
{
lblblank.Show();
lblblank.Text = answer.ToString();
}
private void panel_MouseLeave(object sender, EventArgs e)
{
lblblank.Hide();
}
Edit
~~~
What does it mean that any layout element as a parent-element for the
label? Could you explain more?
What I meant was to just create a new panel (or layout-element) and put the label into it as a child. See the picture below:
If you set that up correctly, the code snippet I posted above will work just fine. This solution does not prevent the MouseLeave event from triggering when your mouse enters the label. Therefore you could use an alternative solution using the MouseMove event.
Alternative
using System;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
this.InitializeComponent();
// Subscribe to the MouseMove event
this.panel.MouseMove += this.panel_MouseMove;
}
private void panel_MouseMove(object sender, MouseEventArgs e)
{
// Checks if current mouse position is within the panel
if (this.panel.Bounds.Contains(new Point(e.X, e.Y)))
{
// Current mouse position within the panel
this.label.Show();
return;
}
// Current mouse position outside the panel
this.label.Hide();
}
}
}

Multiple OnClick events in c#

I want to ask if i have multiple labels with same function Onclick but with different parameters. How i can handle them without make 30 methods.
I want to make A-Z Filter in windows forms application with C#. I have label for each character (A,B,C,D....,Z). Also i have TreeView with data from DB.
private void labelLetter1_Click(object sender, EventArgs e)
{
//this.labelLetter1.Text
// get value of the label and refresh treeview
}
I want to make this on every characters but without repeat same code.
subscribe an example event to other ones. try like this:
private void labelLetter1_Click(object sender, EventArgs e)
{
Label lbl = (Label) sender;
var text = lbl.Text;
//this.labelLetter1.Text
// get value of the label and refresh treeview
}
now set this event to other labels from Properties window.
The sender parameter is going to be the original object that triggered the event. In your case, it is going to be a Label. This means you could cast the object to a Label.
Additionally you could make a single label_click method and have all labels user that single method.
For example:
private void label_Click(object sender, EventArgs e)
{
String labelText = (sender as Label).Text;
//Your process
}

Why it is not Possible to call textBox1_KeyPress() event from some Button Click event.?

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn0_Click(object sender, EventArgs e)
{
MessageBox.Show("called btn 0 click..");
KeyPressEventArgs e0 = new KeyPressEventArgs('0');
textBox1_KeyPress(sender, e0);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
MessageBox.Show("called txtbox_keypress event...");
}
}
Am sorry if this is a silly question,I have just started to learn windows forms, I still find material on the internet confusing.I want to implement calculator. So when number button is pressed it should be filled in textbox. So I thought calling textBox1_keypress() event from button click event would work??? but its not working,
I can manually write the logic in button click event to fill text in text box but if i do so, i have to do the same thing in button1_KeyPress event too. so it would be duplication of code right??...so i thought solution was to call textBox1_KeyPress() event from both button click event and button key press event...but its not working .So what should i do???..is there any other approach which should i follow.
so it would be duplication of code right??
Yes, it would be. So you can do
private void btn0_Click(object sender, EventArgs e)
{
CommonMethod(e);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
CommonMethod(e);
}
private void CommonMethod(EventArgs e)
{
//Your logic here.
}
The TextBox KeyPress event handler (textBox1_KeyPress) is called after the user presses a key. The KeyPressEventArgs parameter includes information such as what key was pressed. So calling it from your btn0_Click method isn't going to set the text for the TextBox.
Rather, you want to (probably) append whatever number the user pressed to the text already present in the TextBox. Something like
private void btn0_Click(object sender, EventArgs e)
{
textBox1.Text += "0";
}
might be closer to what you're trying to accomplish.
You could put the logic in an extra function like so:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn0_Click(object sender, EventArgs e)
{
NumberLogic(0),
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// I don't know right now if e contains the key pressed. If not replace by the correct argument
NumberLogic(Convert.ToInt32(e));
}
void NumberLogic(int numberPressed){
MessageBox.Show("Button " + numberPressed.ToString() + " pressed.");
}
}
You don't want to tie the events together like that.
A key-press is one thing, handled in one way.
A button click is something totally different and should be handled as such.
The basic reason is this,
The button doesn't know what number it is, you need to tell it that.
A key-press on the other hand, knows what number was pressed.
If you REALLY want to, for some reason, you could use SendKeys to trigger your key-press event in a round-about way, from the button.
SendKeys.SendWait("0");
I can suggest to you to use an Tag Property of the Buttons. Put in it the value of each button in Design mode or in Constructor, create one button event handler for all buttons and use Tag value:
Constructor:
button1.Tag = 1;
button2.Tag = 2;
button1.Click += buttons_Click;
button2.Click += buttons_Click;
Event hadler:
private void buttons_Click(object sender, EventArgs e)
{
textBox1.Text = ((Button)sender).Tag.ToString();
}

Updating a textbox using no input controls

I have a windows form application which consists of a bunch of controls, but more specifically, two textBoxes. One of them is read only. The read only textBox value is supposed to be the same as the textBox that the user can type into.
So if the user types "Hello World" into textBox A, the value in textBox B should be automatically updated to "Hello World".
How do I go about doing this? I know I just need to set the text values, I'm just not sure where I place the code to get it done automatically rather than executed when a button is click or something along those lines.
TextChanged event:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Text = textBox1.Text;
}
It sounds like you want something like:
writableTextBox.TextChanged += delegate {
readonlyTextBox.Text = writableTextBox.Text;
};
In other words, whenever the text in one textbox changes, update the other. This uses the Control.TextChanged event.
If you want textBoxB to be updated as soon as the text of textBoxA is changed (i.e immediately after the user press a key in textBoxA) the event is TextChanged:
this.textBoxA.TextChanged += new System.EventHandler(this.textBoxA_TextChanged);
private void textBoxA_TextChanged(object sender, EventArgs e)
{
textBoxB.Text = textBoxA.Text;
}
If you prefer to update the text in textBoxB only after the user has finished to edit textBoxA, you should use the Leave event:
this.textBoxA.Leave += new System.EventHandler(this.textBoxA_Leave);
private void textBoxA_Leave(object sender, EventArgs e)
{
textBoxB.Text = textBoxA.Text;
}
This should do what you need:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Text = textBox1.Text;
}
Even shorter (better?) than the event approach is using winform's databinding. Just use this right after the InitializeComponents call:
readonlyTextBox.DataBindings.Add("Text", writableTextBox, "Text");

Categories