Auto refresh labels as text boxes text input data into method - c#

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.

Related

How to make two textboxes working from both sides? [duplicate]

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

Firing The DataGridView CellValueChanged Event Immediately for doing thousand separator

I kindly ask you patiently read my story for solving a seemingly simple problem,
my main purpose is to do thousand separator in datagridview,
It means when I am typing 12345 it becomes 12,345
the difference with other task is to do this when the user is typing not when he or she leave the cell,
I couldnt find any method in datagridview events that be fired whenever I add a digit in cell, for example if the purpose is to write 12345 in feeColumn it has to be fired five times,
After many research I came across with this code to do, but it has some problems:
myGrid:
ItemName Quantity FeeColumn
Private void grdTrading_CurrentCellDirtyStateChanged(object sender, System.EventArgs e)
{
If (grdTrading.IsCurrentCellDirty )
{
grdTrading.CommitEdit(DataGridViewDataErrorContexts.Commit)
}
}
Private void grdTrading_CellValueChanged(object sender , System.Windows.FormsDataGridViewCellEventArgs e)
{
grdTrading.Columns[ColumnFee.Name].DefaultCellStyle.Format=(Decimal.Parse(grdTrading.Rows[0].Cells[ColumnFee.Name].Value.Tostring())).Tostring("#,##0")
}
Now What is wrong?
When it firstly goes to grdTrading_CurrentCellDirtyStateChanged and do commitedit it no longer allow to put any data in cell and remove the data while the user change its cell
now you suppose there is data, it successfully be run, and even run cellValueChanged once I add any digit to the fee column,
I mean 1 then 12 then 123 then 1234 then 12345
but still there is no comma in my grid when I am typing,
I am really fed up with this problem, any help or any other solution is welcome to me pal,
Just as Reza Aghaei has rightly pointed out, the idea here is to handle the DataGridView.EditingControlShowing event. His advice to practice on the TextBox control is spot on, and I see you've generally the idea from your link in comments. You just need to hook it all up now:
this.dataGridView1.EditingControlShowing += this.DataGridView1_EditingControlShowing;
private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is TextBox)
{
TextBox tb = e.Control as TextBox;
tb.TextChanged -= Tb_TextChanged;
tb.TextChanged += Tb_TextChanged;
}
}
Now you can handle the TextBox.TextChanged event similarly to what you tried in your other question. Below I've shown my implementation, with some tweaks to the position of the selection cursor more relative to its previous position.
private void Tb_TextChanged(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
ulong value;
string text = tb.Text.Replace(",", "");
string old = tb.Text;
if (ulong.TryParse(text, out value))
{
int start = tb.SelectionStart;
tb.Text = string.Format("{0:n0}", value);
tb.SelectionStart = Math.Max(0, start + tb.Text.Length - old.Length);
if (tb.SelectionStart > 0 && tb.Text[tb.SelectionStart - 1] == ',')
{
tb.SelectionStart--;
}
}
}
Hope this helps.
Sidenote: If this annoys your users (entirely plausible as this is not normal expected behavior - changing user input during a live edit), it's easy enough to revert to:
private void DataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
ulong value;
if (ulong.TryParse(e.Value?.ToString(), out value))
{
e.Value = string.Format("{0:n0}", value);
}
}

System.FormatException occurred in mscorlib.dll when converting it int32

I know, i know there are lots and lots of questions asking on here about this error, each with their own response, but its easier to work off a response regarding your own code rather than someone else's
I have been working on this program for some time for a college assignment, and as soon as i started putting in the class to calculate the totals of things it now crashes,
I don't know where to look so i'll post my main code
enter code here
namespace Till
public partial class MainWindow : Window
{
Calculator calc = new Calculator();
public MainWindow()
{
InitializeComponent();
}
public bool User;
public bool tillopen = false;
private void button_Click(object sender, RoutedEventArgs e)
{
//button clone thingy
Button btn = (Button)sender;
label.Content = label.Content + btn.Content.ToString();
Console.Beep(); // makes the buttons beep
}
private void clear_Click(object sender, RoutedEventArgs e)
{
// Clear
label.Content = "";
}
private void Button_Submit_Click(object sender, RoutedEventArgs e)
{
// submit
listView.Items.Add(label.Content);
label.Content = "";
calc.setSoldItems(Convert.ToInt32(label.Content)); /// it breaks on this line///
}
private void button13_Click(object sender, RoutedEventArgs e)
{
//void sale
label.Content = "";
listView.Items.Clear();
}
private void button15_Click(object sender, RoutedEventArgs e)
{
//pound
label.Content = "1.00";
}
private void button12_Click(object sender, RoutedEventArgs e)
{
//till open close
tillopen = true;
}
private void button16_Click(object sender, RoutedEventArgs e)
{
Login m = new Login();
m.Show();
this.Close();
}
private void button14_Click(object sender, RoutedEventArgs e)
{
label.Content = "2.00"; // 2 pound
}
private void button17_Click(object sender, RoutedEventArgs e)
{
label.Content = calc.finish();
}
}
I have tried to re-create the error in another WPF (converting a to an int32) and it works fine, i know this is an issue with my code itself, i have tried using other machine and using different versions of visual studio itself, so we came to the assumption its this code itself and not a broken dll file
So before I sit down with my Teacher and spend all day going though my code step by step im asking around for help in order to save both of our time, This assignment is due in in 3 weeks, and it decides to break on me now.
thankies
To replicate this error, i press a number button on my Windows form, them hit the submit button i created (which starts the conversion) If a copy of my class which handles all of this is needed im happy to post it
In the method button_click, you have assigned value as
label.Content = label.Content + btn.Content.ToString();
which is a string value to the label and the values are concatenated instead of add.
and when you are reading it, you are converting it in Int32. which will give exception as it will not contain any integer value to it.
You can add the value like this:
label.Content = (Convert.ToInt32(label.Content) + Convert.ToInt32(btn.Content)).ToString();
and check before converting if the label has blank values in it, if it has do not convert them, and only convert the value if it has some values it will not give any error. Also do not assign any values other that numerical digits.
You are calculating:
Convert.ToInt32(label.Content)
but on the line before you set:
label.Content = "";
so this means you are calculating
Convert.ToInt32("")
which gives you a FormatException.
Perhaps you should use the value of label.Content before you overwrite it?

C#. How to use pass multiple text boxes into method and automatically refresh label

my first post here.
I'm building a calculator that takes user input via text box and converts to a double and passes those numbers into a custom class that contains a formula(the answer is converted back to a string once complete). I have everything working, but I would like the label with the answer to automatically update once the text boxes are filled out. The label text output is correct once clicked on.
heres the code I have for the label so far...
private void lblUtil1_Click(object sender, EventArgs e)
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
lblUtil1.Text = UtilRounded1.ToString() + "%";
}
Is there something that can detect if all the pertinent fields are completed or will this require a loop? I greatly appreciate all help and look forward to being a part of this community!
growthtek
One approach would be to make this:
private void lblUtil1_Click(object sender, EventArgs e)
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
lblUtil1.Text = UtilRounded1.ToString() + "%";
}
a shared method:
private void Calculate();
{
dblUtil1 = Tinseth.Bigness(dblSG) * Tinseth.BTFactor(dblBT1);
double UtilRounded1 = Math.Round(dblUtil1 * 100);
lblUtil1.Text = UtilRounded1.ToString() + "%";
}
and get rid of the Click event. Then consume the text boxes Validated event:
private void TextBox_Validated(object sender, EventArgs e)
{
Calculate();
}
Now hook all of the text boxes Validated events up to this same handler. Now when the user leaves the text box, it will calculate automatically.
The Validated event could just as easily be the TextChanged event as well. That will calculate every time they type a number. But that's probably too frequent.
Create one function that does the calculation then bind that function to the changed event on all the textboxes.
I would not run the calculation every time as Michael or Measuring suggested.
Instead, just put a few if statements in your click event that test to see if the required boxes have values. If they don't, then show a message saying they need to fill it out.
Something like:
if (String.IsNullOrEmpty(TextBox1.Text)) {
MessageBox.Show("TextBox1 is empty");
return;
}

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