This question already has answers here:
C# update two text boxes at the same time?
(4 answers)
Closed 3 years ago.
I am making a simple unit converter in winforms, which means I'd be needing two Textboxes, in textbox1 'from' value is entered and in textbox2 the converted value is printed out. I want to make it work the other way around too i.e. to take input from textbox2 and to print the converted value out in textbox1. How am I supposed to do that?
You have to implement TextChanged event handlers for both TextBoxes; the only difficulty is to understand which control (textBox1 or textBox2)
has been changed by user (in order to prevent infinite loop when textBox1s value converts to textBox2s which in turn converts to textBox1s etc.). You can either check Focused:
private void textBox1_TextChanged(object sender, EventArgs e) {
// Do nothing, if user is changing some other control (e.g. textBox2)
if (!(sender as Control).Focused)
return;
// Having textBox1.Text value convert it forward to textBox2.Text
textBox2.Text = Convert(textBox1.Text);
}
private void textBox2_TextChanged(object sender, EventArgs e) {
// Do nothing, if user is changing some other control (e.g. textBox1)
if (!(sender as Control).Focused)
return;
// Having textBox2.Text value convert it backward to textBox1.Text
textBox1.Text = ReverseConvert(textBox2.Text);
}
Or play with event handlers (which is more flexible esp. if you can start conversion, by, say, button click, so neither textBox1 nor textBox2 have focus):
private void textBox1_TextChanged(object sender, EventArgs e) {
textBox2.TextChange -= textBox2_TextChanged;
try {
// Since textBox2.TextChanged switched off,
// changing textBox2.Text will not cause textBox1.Text change
textBox2.Text = Convert(textBox1.Text);
}
finally {
textBox2.TextChange += textBox2_TextChanged;
}
}
private void textBox2_TextChanged(object sender, EventArgs e) {
textBox1.TextChange -= textBox1_TextChanged;
try {
// Since textBox1.TextChanged switched off,
// changing textBox1.Text will not cause textBox2.Text change
textBox1.Text = ReverseConvert(textBox2.Text);
}
finally {
textBox1.TextChange += textBox1_TextChanged;
}
}
You can handle both textbox's Text change event in one Event handler (it will trigger event two times)
private void textBox_TextChanged(object sender, EventArgs e)
{
if (((TextBox)sender).Equals(textBox1))
textBox2.Text = Convert((TextBox)sender).Text);
else
textBox1.Text = ReverseConvert((TextBox)sender).Text);
}
Related
I used System.Globalization.CultureInfo.InvariantCulture on my Textbox, but whenever I enter the Textbox and leave without altering the value it adds two more zeros, how can I sort this out?
private void textBox1_Leave_1(object sender, EventArgs e) {
double txt = double.Parse(textBox1.Text,
System.Globalization.CultureInfo.InvariantCulture);
textBox1.Text = txt.ToString("N2");
return;
}
Well, in general case, you can keep a collection of Coltrols which were manually edited and on control leaving check if the control is in the collection. Assuming that you work with WinForms:
using System.Globalization;
...
private readonly HashSet<Control> m_EditedControls = new HashSet<Control>();
// On each textBox1 change we should decide if we are going
// to update control's Text on leave or not
private void textBox1_TextChanged(object sender, EventArgs e) {
// If TextBox1 was edited while having keyboard focus,
// i.e. user got focus and edit the textbox manually
// put textbox as edited
if (sender is TextBox box && box.Focused)
m_EditedControls.Add(box);
}
Then on leaving textBox1 you can check if textBox1 has been edited manually:
// On leaving textBox1 we and an additional check
// if textBox1 has been edited manually
private void textBox1_Leave(object sender, EventArgs e) {
if (sender is TextBox box &&
m_EditedControls.Contains(box) &&
double.TryParse(box.Text, CultureInfo.InvariantCulture, out var value)) {
box.Text = value.ToString("N2", CultureInfo.InvariantCulture);
m_EditedControls.Remove(box);
}
}
Here is my method that I' am trying to have automatically refresh my label. When I have my label as a click event...the answer refreshes and is correct.
private void Calculate()
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
strUtil1 = UtilRounded1.ToString() + "%";
}
Here is the Validated label event that does not update when text is changed in my text boxes.
private void lblUtil1_Validated(object sender, EventArgs e)
{
Calculate();
}
If this is correct...what am I missing? is there something I need to do on the text boxes that will trigger validation?
I have also tried a text changed event that yields the error cannot implicitly convert type void(or any type for that matter) to EventHandler. Here is the code.
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
lblUtil1.TextChanged += Calculate();
}
Any help is appreciated! I've been banging my head on my keyboard for a day now.
First at all, you have to handle events for the TextBox that you input value to calculate, such as when you change vale in the TextBox or validate it.
So if you have textBox1 then you should have this handling (trigger when value in textBox1 is changed)
private void textBox1_TextChanged(object sender, EventArgs e)
{
lblUtil1.Text = Calculate();
}
I assume that you want to display value in strUtil1 at the label lblUtil1, so you have to change your Calculate method like this
private string Calculate()
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
strUtil1 = UtilRounded1.ToString() + "%";
return strUtil1;
}
EDITED
This is a sample code for validate the required TextBoxes.
private void textBox1_Validating(object sender, CancelEventArgs e)
{
if (textBox1.Text == "")
{
e.Cancel = true;
lblUtil1.Text = "textBox1 is required!";
}
}
Try calling yourlabelname.Refresh() i.e like
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
lblUtil1.TextChanged = Calculate();
lblUtil1.Refresh();
}
or
private void lblUtil1_TextChanged(object sender, EventArgs e)
{
Calculate();
lblUtil1.Refresh();
}
You need to do a couple things.
First, stop using "hungarian" notation. It's bad. It's bad for a lot of reasons. MS even says, "don't use hungarian" as most people get it wrong as your code shows. Instead, name your variables appropriately. For example, dblSG has absolutely zero meaning.
Second, please reread Michael's answer to your question from yesterday ( https://stackoverflow.com/a/20026642/2424 ). He did NOT say to use lblUtil1_Validated. He said to use TextBox_Validated. In other words, the event you should have your calculation run on is with the textbox fields on your form. He also suggested you just use the textboxes TextChanged events in order to cause the calculation to run as they are typing. Personally, I don't agree with that but whatever.
A third possible option is to simply go back to your original solution. Meaning, just run the calculation when the label is clicked. In which case you should refer back to your original question as Michael failed to answer it.
I have numeric buttons which when pressed display the number in different text boxes. Now my problem is that i want check which textbox has focus so that the number pressed will be entered in that textbox.
My Code:
private void btn_one_Click(object sender, EventArgs e)
{
if (txt_one.Focused==true)
{
txt_one.Text += btn_one.Text;
}
else if (txt_two.Focused==true)
{
txt_two.Text += btn_one.Text;
}
}
Now my problem is that the above code is not working what is wrong and what will be the solution? I even used something like this
private void btn_one_Click(object sender, EventArgs e)
{
if (txt_one.Focus()==true)
{
txt_one.Text += btn_one.Text;
}
else if (txt_two.Focus()=true)
{
txt_two.Text += btn_one.Text;
}
}
In both the above cases the text is entered in both the text boxes. Any solutions.
This problem is a little tricky (with my experience dealing with Enter, Focus, LostFocus, Leave events, all these things sometimes make your head ache a lot and you should avoid dealing with them if possible), at the time you click your Button, the current Focused control you can know is exactly the Button (ActiveControl is one short way to access it). So the solution is we have to record the track of focused TextBox, hold it in a reference and use it when needed. In fact if the control other than one of your TextBoxes is focused, we have to reset the variable lastFocused to null:
TextBox lastFocused;
//Enter event handler for all your TextBoxes
private void TextBoxes_Enter(object sender, EventArgs e){
lastFocused = sender as TextBox;
}
//Click event handler for your button
private void btn_one_Click(object sender, EventArgs e){
if(lastFocused != null) lastFocused.Text += btn_one.Text;
}
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");
i need to based in what the user wrote in the edition of a node label, rewrite that label with other text. Example if the user wrote "NewNodeName" I want that the node text after finish the edition be "S :NewNodeName".
I try this two codes and i don't know why neither work
private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
e.Node.Text = "S :"+ e.Label;
}
and also:
private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
treeView1.SelectedNode.Text = "S :"+ e.Label;
}
Yes, doesn't work, the Text property gets the label value after this event runs. Which is why e.Cancel works. So the Text value you assigned will be overwritten again by code that runs after raising this event. Code inside of the native Windows control.
There is no AfterAfterLabelEdit event and you cannot alter e.Label in the event handler, you need a trick. Change the Text property after the event stopped running. Elegantly done by using Control.BeginInvoke(). Like this:
private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) {
this.BeginInvoke((MethodInvoker)delegate { e.Node.Text = "S: " + e.Node.Text; });
}
It's quite late to answer this question, but here's another solution:
1) Remove the part that you want user not to edit of the node label right before you call BeginEdit()
2) In AfterLabelEdit(), set the node text as you want and set NodeLabelEditEventArgs.CancelEdit = true so that the text user input won't replace the text you set
private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Node == null) return;
e.Node.Text = e.Node.Text.Substring(3, e.Node.Text.Length - 3);
e.Node.BeginEdit();
}
private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
e.Node.Text = "S :" + e.Label;
e.CancelEdit = true;
}