How to add a unit at the end of textbox in C# - c#

I find this code from here to add a unit like minutes or kg at the end of a textbox after the number was entered. in C#
private void CowAgetxtBox_Leave(object sender, EventArgs e)
{
{
CowAgetxtBox.Text = CowAgetxtBox.Text + " Month";
}
}
private void CowAgetxtBox_Enter(object sender, EventArgs e)
{
{
CowAgetxtBox.Text = CowAgetxtBox.Text.Replace(" Month", "");
}
}
but I don't know how get that number,
I use this Code but it doesn't work
int Age = int.Parse(CowAgetxtBox.Text);

Actually it's not a good idea to put the unit inside the textbox, this will cause a lot of problems in data validation, localization, casting, ...
better to put it outside the textbox :)

You just need to do a process similar you when the user focused on the text box.
int Age = int.Parse(CowAgetxtBox.Text.Replace(" Month", ""));
This will get the job done.

It seems that
CowAgetxtBox.Text
this statement contains value other then number thats why this statment
int Age = int.Parse(CowAgetxtBox.Text);
is not working remove " Month" from the first function

If the unit label changes, this might work in more cases for you:
int Age = int.Parse(CowAgetxtBox.Text.Split(' ')[0]);

You can add a property like the following:
int Age {
get { return Convert.ToInt32(CowAgetxtBox.Text.Replace(" Month", "")); }
}

Related

Storing value from try for use in second try C#

Good day fellow helpers, i have following problem:
(running MS Visual Community Edition 2015)
private void button4_Click(object sender, EventArgs e) // Senden
{
serialPort2.WriteLine("SR,00,002\r\n");
textBox1.Text = "gesendet";
textBox3.Text = "";
try
{
System.IO.StreamReader file = new System.IO.StreamReader("C:\\blub.txt");
String line = file.ReadToEnd();
string Hallo = line; \\in the beginning there is "0" in the file
file.Close();
decimal counter = Convert.ToDecimal(Hallo); \\just for testing
counter++;
string b = serialPort2.ReadLine();
string[] b1 = Regex.Split(b, "SR,00,002,"); \\cuts off unwanted input from device
decimal b2 = decimal.Parse(b1[1]); \\number like -3000
System.IO.StreamWriter test = new System.IO.StreamWriter("C:\\blub.txt");
test.WriteLine(counter);
test.Close();
textBox7.Text = "Das ist counter:" + counter;
}
catch (TimeoutException)
{
textBox3.Text = "Timeout";
throw;
}
}
Now, the Serialport is a device that returns a lengthmeasurment. As it is a bit weird, or just the way its build it start with a negitve number (between -5000 and -3370). Now as i want to get measurement on the screen that is realistic i want to set the value to 0 and calculate the difference.
Means: I start the programm - press send - get a value (say -3000) - press send again (after pushing the seonsor in) and get the value that its been pushed in > 0 by adding the difference to 0.
I only learned to store values externally when i had a C course a year back like i did within my programm. Is there a way to store the value from the first measurement in the programm so i can use it on the next send/try?
The counter was just for testing and I would exchange it for the "decimal b2"
I hope there is an easy fix for that, not really a pro with C# yet but i'm eager to learn. I thank the willing helpers in advance, MfG, Chris
OK, I will simplify this in order to show concept so it will not have all the code you are actually using.
So, what you want is to click on button, get some values and store them for next click.
Value is stored in variable. If you have variable in function that is handler for click event, as soon as function completes execution, value will be destroyed.
So, what you need is to create variable in outer scope (class level). Your function is already in class of the form so let's get to code:
class Form1
{
string BetweenClickStorage;
private void button4_Click(object sender, EventArgs e)
{
//Load data here
BetweenClickStorage = LoadedData;
}
}
After this, when you click again on the button, value will still be in BetweenClickStorage. It will be also available to all other buttons click handlers and other code in that form.
If I'm understanding your question correctly, the answer is simply to declare a variable outside the try/catch:
//declare variable //
var measurement;
// TRY #1 //
try
{
//assign value to the variable here
}
catch
{
}
// TRY #2 //
try
{
// reference variable here
}
catch
{
}

Why isn't this causing an infinite loop of events?

I have a simple application that reverses any text typed to it in another textbox. The catch is, you can modify either textbox and the changes will be (literally) reflected in the other.
I wrote this code, believing for it to cause problems.
private void realText_TextChanged(object sender, EventArgs e)
{
mirrorText.Text = mirror(realText.Text);
}
private void mirrorText_TextChanged(object sender, EventArgs e)
{
realText.Text = mirror(mirrorText.Text);
}
private string mirror(string text)
{
return new string(text.Reverse().ToArray()).Replace("\n\r", "\r\n");
}
I then tried it out, believing that it would cause an infinite loop (realText changes mirrorText, another event happens, mirrorText changes realText, etc). However, nothing except the intended behavior happened.
I'm of course happy about this, I could just leave it here. Or could I?
I'm quite sure the TextChanged event is supposed to be fired whenever Text is changed. Is this intended behavior of some error protection in the events, or was I just lucky? Can this code misbehave on another computer, with other build settings, etc? It can be easily fixed:
private void realText_TextChanged(object sender, EventArgs e)
{
if (realText.Focused)
{
mirrorText.Text = Mirror(realText.Text);
}
}
I'll probably do it anyway to be safe, but is it required to check this? (I'm not even going to ask if it's recommended.)
Per the comments, and as already answered, the TextChanged event is not getting raised when you set the Text property to the value it already has.
It's not clear whether this is something you can safely rely upon. It is a sensible optimisation, and I would be very surprised if future versions of .NET Framework drop it, but I cannot speak for older versions, nor for third-party implementations (Mono).
To be absolutely safe, I would not use the Focused check you put in your question. I would do exactly what the Text setter does now.
private void realText_TextChanged(object sender, EventArgs e)
{
var newMirrorText = Mirror(realText.Text);
if (mirrorText.Text != newMirrorText)
mirrorText.Text = newMirrorText;
}
This has the same advantage of preventing infinite recursion, but plays more nicely with other code you may put in your form that changes the text as a result of some other event.
The reason it doesn't cause a loop is that it checks whether the Text property actually changed, i.e. if the new value does not equal the old value. In your case the mirror function happens to reverse itself, which leads to the same text after two passes.
It's pretty easy to check.
First, replace both textbox controls with
class T : TextBox
{
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
}
}
}
Second, set the breakpoint on setter. Add these expressions to the Watch window:
Name
Text
value
Third, launch the app, copy '123' from somewhere and paste it to the first textbox. Here it goes:
1st break:
Name: "mirrorText"
Text: ""
value: "321"
2nd break:
Name: "realText"
Text: "123"
value: "123"
3rd... whoops, it does not breaks anymore. To detect why we had to go deeper. Look at referencesource: text box setter does nothing unusual, but TextBoxBase's one looks interesting:
set {
if (value != base.Text) { // Gotcha!
base.Text = value;
if (IsHandleCreated) {
// clear the modified flag
SendMessage(NativeMethods.EM_SETMODIFY, 0, 0);
}
}
}
So, as hvd already answered, the reason is the textbox does not raise TextChanged if old and new values are the same. I don't think the behavior will change, at least for winforms. But if you want more robust solution, here it is:
private void RunOnce(ref bool flag, Action callback)
{
if (!flag)
{
try
{
flag = true;
callback();
}
finally
{
flag = false;
}
}
}
private bool inMirror;
private void realText_TextChanged(object sender, EventArgs e)
{
RunOnce(ref inMirror, () =>
{
mirrorText.Text = mirror(realText.Text);
});
}
private void mirrorText_TextChanged(object sender, EventArgs e)
{
RunOnce(ref inMirror, () =>
{
realText.Text = mirror(mirrorText.Text);
});
}
private string mirror(string text)
{
return new string(text.Reverse().ToArray()).Replace("\n\r", "\r\n");
}
P.S. mirror() will fail on surrogate pairs. Here're some solutions.
If textbox has a Text, and we try to change it with the same Text, the TextChange event is not raising because new text is same as the previous.
In your code, the realText_TextChanged event reverses the text and changes the mirrorText with it.
The mirrorText_TextChanged event reverses the text and try to change the realText.
The realText has already this text and does not raises the realText_TextChanged event.

Accelerate add text to a TextBox

I have code to set text of TexBox as
textBox1.Text = s;
where s is a string that have more than 100,000 char, and it take long time to show text on textBox.
Anybody have solution to make it faster ?
To do that split the s string into many strings, and use the AppendText to add those subStrings, if you check MSDN you will see that :
The AppendText method enables the user to append text to the contents of a text control without using text concatenation, which, can yield better performance when many concatenations are required.
public string s = "Put you terribly long string here";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//For responsiveness
textBox1.BeginInvoke(new Action(() =>
{
//Here's your logic
for (int i = 0; i < s.Length; i += 1000)
{
//This if is just for security
if (i+1000 > s.Length)
{
//Here's your AppendText
textBox1.AppendText(s.Substring(i, s.Length-i));
}
else
{
//And it's here as well
textBox1.AppendText(s.Substring(i, 1000));
}
}
}));
}
I used the value 1000, you can use 1500 , 2000 , choose the one that gives better result.
Hope this helps.
Update :
AppendText is available for both WindowsForms and WPF, too bad can't find it on WindowsPhone and WinRT. so I think this solution may help you a lot
break s in sub strings and when you pass first sub string to the text box it will appear after that it concatenate to the second and so on.
other way is that use loop to set the value
for(int i=0;i<s.length; i++)
{
textBox1.Text += s[i];
}
may these helps you

Add items to a dgv from saved variables in another class (C# winForms)

Im relatively new to programming and still learning. I have just made a calculator, and then I got the idea that I wanted to save the two input numbers (value1, value2) and the result in a datagridview in another winform.
First of i added a button (bSave) for saving it.
My first attempt was with:
dgvSavedResults.Rows.Add(tbValue1.Text, tbValue2.Text, tbResult.Text);" and works OK.
My next attempt was to save all of it in another class:
public class Information
{
private string value1;
private string value2;
private string result;
public string Value1
{
get { return value1; }
set { value1 = value; }
}
public string Value2
{
get { return value2; }
set { value2 = value; }
}
public string Result
{
get { return result; }
set { result = value; }
}
}
And in the calculator form it looks like this when i click the save button:
private void bSave_Click(object sender, EventArgs e)
{
Information info = new Information();
info.Value1 = tbTal1.Text;
info.Value2 = tbTal2.Text;
info.Result = tbResultat.Text;
}
I think i need to use a datatable and the loop through whats inside the Information-class.
But i have really no idea how to make this work. I have googled around but i havent found something that i understand. Am i on the right track? Or am i totally wrong with my thinking?
If anyone could take the time to explain to me what to do and maybe show me an example how to do it would be really appreciated. Thanks
You can have a list of your results:
BindingList<Information> resultsList = new BindingList<Information>();
Bind it to DataGridView using BindingSource:
BindingSource resultsBindingSource = new BindingSource();
this.resultsBindingSource.DataSource = resultsList;
this.dgvSavedResults.DataSource = this.resultsBindingSource ;
then:
private void bSave_Click(object sender, EventArgs e)
{
Information info = new Information();
info.Value1 = tbTal1.Text;
info.Value2 = tbTal2.Text;
info.Result = tbResultat.Text;
resultsList.Add(info);
}
And it's done.
Also, depending on how you want to add columns, you can do it manually, or you can generate it automatically from public properties of your Information class:
dgvSavedResults.AutoGenerateColumns=true;
EDIT:
to properly reflect changes on your datagridview, its better to use BindingList instead of List

C# Grabbing Input Text and pushing to an integer

I am trying to get this piece of code working in C#, what I want to do is if a textfield is updated to validate its an integer (HP is an integer).
So by attempting to convert the input to an integer, I either get a new integer, and sets the value to it, or if it fails, it takes the previous verified value and pushes back to the text field (pretty much ignoring the input, updating it, and it is now a validated input).
In my head this is all logic and working, in effect its not. Please help.
private void Input_HP_TextChanged(object sender, EventArgs e)
{
Try
{
HP = Convert.ToInt32(Input_HP.Text);
}
catch(Exception e)
{
Input_HP.Text = HP;
}
}
You can use try.parse, but you will want to set it to a temporary variable. In your case, using HP will overwrite your variable you want to save.
int tempInt;
if(Int32.TryParse(Input_HP.Text, out tempint))
{
HP = tempInt;
}
else
{
Input_HP.Text = HP.ToString();
}
Int.TryParse is probably what you are looking for:
int HP;
if (int.TryParse(Input_HP.Text, out HP))
{
// the number is an integer at this point
}
If HP is an integer you cannot directly assign it to the Text property because this is of type String. This should be a compile time error, for this part of the code you should be using the .ToString() function...
Input_HP.Text = HP.ToString();
Of course, you should be using a TryParse for this conversion anyway. I guess what you want is something like this...
private void Input_HP_TextChanged(object sender, EventArgs e)
{
int i = 0;
if(int.TryParse(Input_HP.Text, out i))
{
HP = i;
}
else
{
Input_HP.Text = i.ToString();
}
}

Categories

Resources