I am having trouble with getting a value in a text box before the value is changed either by user input or programmatically.
I figure it has to do with the _TextChanged event but once this executes how do I get the old value which was already there before the change?
For example number 3 is in the text field. The number then changes to 4 how do I save 3?
Thanks in advance!
Do not store anything in the TextBox. Use it only to display/edit value.
private string value;
private void textBox1_TextChanged(object sender, EventArgs e)
{
// at this moment value is still old
var oldValue = value;
value = ((TextBox)sender).Text; // text1.Text
// here you have oldValue and new value
}
Maybe you don't want to update value after each TextChanged. Maybe you will do it when form is closed, some button is pressed, etc.
Anyhow idea should be clear: if you need to have old value, then store it somewhere yourself (as a variable, as a Tag, as application setting, exporting, etc.).
Also, take care about how user will work. If TextBox contains 3, then user may first press 4 and only then delete 3. Or user may accidentally press 54. Which of those will be old value: 3, 34, 54 ? Simply to demonstrate you, what there could be consequent problems to having concept of old value. Mayhaps you don't want it and there is better solution to what you are trying to solve by getting old value.
Why not save the current value in the textbox in a variable during the textchanged event. That way, it is the "previous" value when the event is fired again.
You can save the value of textbox in some variable.
For example
string currentVal = txtName.Text;
string currentVal can be used as a previous value in text_changed event.
Have you tried making a timer. Every tick you write the input to a string. If the input of the textbox is not equal to the content in the string, you trigger what you wanted to do. That way you can trigger a void with the old input.
private string oldInput;
....
void TimerTick(Object source, ElapsedEventArgs e)
{
if (oldInput != MyTextBox.Text) MyVoid(oldInput);
oldInput = MyTextBox.Text;
}
Related
i'm having a problem . I'm trying to make an application in C# (Windows Form Application) and i'm stuck into something.
I want to do a log-in form like in the photo. For username i'm having a combo-box where i can choose the user , but for password i want to place some buttons(like in the photo) , and when i press the button 1 for example , i want to have a string which is 1 .After that i will place 2 ,and i want to concatenate 1 and 2 into that string . Do you know how can i do that
In your case, I believe you have one event for each button. In each event you could just sum the values to a global variable or directly change the textbox. Like this:
txtPassword.Text += "0"; //the 0 button
It will change the textbox value and when you click "Sign in" you can get the txtPassword.Text as the final string.
You can also declare a string or StringBuilder globally and append the value in every button click, tho this won't change the textbox text directly.
Use a StringBuilder to concatenate strings.
StringBuilder builder = new StringBuilder();
builder.Append(a);// where "a" is your input character
And whenever you get a new character input call builder.Append(a);
In the end you get your final string by calling builder.ToString();
As a variation on the answer from #LeoFormaggi, you could have a single event handler for all the numeric buttons (i.e., one that every button's click handler points to). Then, in the handler:
var buttonText = (sender as Button)?.Text;
txtPassword.Text += buttonText ?? String.Empty;
Don't forget to make that textbox be a password field (by setting the PasswordChar property).
You don't want to bother with a StringBuilder here. It's normally the right tool for concatenating strings, but it buys you nothing in this case since you want the result to appear immediately in the text box. In this case it would simply add overhead for no good reason.
i want to thank you, i made my solution like this :
`private void nb6_Click(object sender, EventArgs e)
{
password_box.Text += "6";
}`
in every button event that i have, the password_box (which is my textbox) and i concatenate everytime the string that i want(in this case is number 6 )
Thank you and have a nice day . :)
So guys i am new in C# and i want to know how to make to label return some values.
One example :
Label1 will be 75 dollars when i click in radiobutton.
When i choose the radiobutton, will change the value of 0 to 75 dollars in the painel,and will be added to the value of the buy.
I already tried some stuffs but didn't worked,i am really freaking out with this.
Please help, I need to do that for the Course of Programming.
You can use Text property for set and get value from label, such as:
int myIntVariable1 = 934;
myLabel.Text = myIntVariable1;
int myIntVariable2 = Convert.ToInt32(myLabel.Text);
Now myIntVariable1 and myIntVariable2 will have 934 value
A label cannot return a value,
if you're using a radio button \ button group, you could need to fire an CheckedChanged event, easiest way would be get the radio buttons on your form, double click for the event to get generated, then use a switch statement to have the label changed
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
label1.Text = "your new value or text here";
}
Also, just as a note of interest for you and the course you're doing, sign up to PluralSight which has mass of courses, and will teach you all you need to know about the fundamentals of C# and much more. You can get a free 10 or 14 day trial and then you can sign up from $29 per month and cancel at any time.
Long time listener, first time caller here. I'm having a strange issue with the TextBox in WinRT C#/XAML that I hope someone may be able to help me with.
Basically, I'm working on creating a Custom Control that essentially requires a second TextBox to be a copy of the first, including showing the same Text, and showing the same Selected Text. Obviously for the Text requirement I simply respond to the TextChanged event on the first TextBox and set the Text of the second TextBox to the Text from the first, which works great.
For the Selected Text requirement I started with a similar solution, and my code for this is as follows:
void TextBox1_SelectionChanged(object sender, RoutedEventArgs e)
{
this.TextBox2.Select(this.TextBox1.SelectionStart, this.TextBox1.SelectionLength);
}
This seemed to work pretty well when initially used with a mouse:
But I'm having a problem when selecting text with Touch. I double-tap within the TextBox to create the first "anchor" as you do in Touch, then drag to begin the selection; but I only ever manage to select a single character normally before the selection stops. The TextBox doesn't lose focus exactly, but the behaviour is similar to that; the selection anchors disappear and I can't continue selecting anything unless I re-double-tap to start a new selection. If I remove the code to select text in TextBox2 then the Touch selection behaves perfectly in TextBox1.
I've been trying to fix this for a while and cannot, I'm not sure if I can get the desired behaviour with WinRT TextBoxes. Does anyone have any ideas? Or perhaps another way to implement a solution with two TextBoxes with this behaviour?
Thanks a lot.
So this is far from an answer, but discovered a few things that maybe will help you or others come up with a potential workaround. Apologies if these are things you've already seen and noted.
First, it's not the call to TextBox2.Select() that's the problem per se. This for instance, works fine for me
private void txt1_SelectionChanged(object sender, RoutedEventArgs e)
{
var start = TextBox1.SelectionStart;
var length = TextBox1.SelectionLength;
TextBox2.Select(3, 5);
}
unfortunately, using start and length versus the hard-coded 3 and 5, that is, the following, DOES NOT WORK:
private void txt1_SelectionChanged(object sender, RoutedEventArgs e)
{
var start = TextBox1.SelectionStart;
var length = TextBox1.SelectionLength;
TextBox2.Select(start, length);
}
I also discovered that I could select TWO characters if I started from the end, but only one from the beginning. That got me to thinking about dispatching the call to set the second selection:
private void txt1_SelectionChanged(object sender, RoutedEventArgs e)
{
var start = TextBox1.SelectionStart;
var length = TextBox1.SelectionLength;
Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low,
() => TextBox2.Select(start, length));
}
Now I can select 2 from the front and 3 and sometimes 4 from the back. Took it a step further, and was able to select as many as six or seven with a really fast swipe.
private void txt1_SelectionChanged(object sender, RoutedEventArgs e)
{
var start = TextBox1.SelectionStart;
var length = TextBox1.SelectionLength;
Dispatcher.RunIdleAsync((v) => Highlight());
}
public void Highlight()
{
TextBox2.Select(TextBox1.SelectionStart, TextBox1.SelectionLength);
}
Seems like the trick to working around this is not setting TextBox2 until whatever vestiges of the TextBox1 SelectionChanged event have completed.
This may be worth registering on Connect.
Mine is only a partial solution as well.
I did some debugging and noticed that the SelectionChanged event is fired throughout the text selection process. In other words, a single finger "swipe" will generate multiple SelectionChanged events.
As you found out, calling TextBox.Select during a text selection gesture affects the gesture itself. Windows seems to stop the gesture after the programmatic text selection.
My workaround is to delay as long as possible calling the TextBox.Select method. This does work well, except for one edge case. Where this method fails is in the following scenario:
The user begins a select gesture, say selecting x characters. The user, without taking their finger off the screen, pauses for a second or two. The user then attempts to select more characters.
My solution does not handle the last bit in the above paragraph. The touch selection after the pause does not actually select anything because my code will have called the TextBox.Select method.
Here is the actual code. As I mentioned above, there are multiple selection changed events fired during a single selection gesture. My code uses a timer along with a counter to only do the programmatic selection when there are no longer any pending touch generated selection changed events.
int _selectCounter = 0;
const int SELECT_TIMER_LENGTH = 500;
async private void TextBox1_SelectionChanged(object sender, RoutedEventArgs e)
{
// _selectCounter is the number of selection changed events that have fired.
// If you are really paranoid, you will want to make sure that if
// _selectCounter reaches MAX_INT, that you reset it to zero.
int mySelectCount = ++_selectCounter;
// start the timer and wait for it to finish
await Task.Delay(SELECT_TIMER_LENGTH);
// If equal (mySelectCount == _selectCounter),
// this means that NO select change events have fired
// during the delay call above. We only do the
// programmatic selection when this is the case.
// Feel free to adjust SELECT_TIMER_LENGTH to suit your needs.
if (mySelectCount == _selectCounter)
{
this.TextBox2.Select(this.TextBox1.SelectionStart, this.TextBox1.SelectionLength);
}
}
Is there a way to make a label automatically update itself so that I don't have to use a button to send out the command. What I have setup is a subtotal textbox, discount textbox, tax label, shipping textbox, and total label. So, when people fill in the subtotal, discount, and shipping, I want the tax label to be calculated, but only if previously a certain state was selected in another part of the form. So then, with all those filled in, I want the total label to be filled in. All of these I know I can do with a button, but I was wondering if there is a way to automate it using C# in Visual Studio.
Thanks.
I use the TextChanged Event to update such values between pairs of textboxes. Here are some extracts of my code:
private void onLongitudeTextChanged(object sender, EventArgs e) {
updateDistanceAndBearing();
}
updateDistanceAndBearing does some error checking - this can be a good idea if the user can put invalid values in and then updates the Text property of the other TextBoxes
I have text boxes but update the label.Text property instead.
It gets more messy (at least I found it so) if you have numeric updowns to get values
You can call a method to update the label in the change events for the controls.
For more detail, please supply more detail.
this is off the top of my head but should get you pretty close...
private void taxChanged(object sender, EventArgs e)
{
updateTax();
}
private void updateTax()
{
// the rest of your logic, checking state, etc.
//
this.Tax.Text = aValueCalculatedInYourLogicAbove;
updateTotal()
}
private void updateTotal()
{
// sum up whatever fields need to be summed
//
this.Tax.Text = aTotalValueCalculatedAbove;
}
Using Windows Mobile 6.5 and C#
The CharacterCasing property seems to be missing from WinMo 6.5 and I decide to just catch the textchanged event and set the text with ToUpper.
This works - but on every keypress, it sends the cursor back to the beginning of the string, not the end.
I know this is old, but hopefully this can help somebody else. I implemented the KeyPress event like the following.
private void TextBox_KeyPress(object sender, KeyPressEventArgs e)
{
e.KeyChar = Char.ToUpper(e.KeyChar);
}
Ritu, just to comment on your answer. You should keep in mind that this might be confusing for a user if the user has positioned the caret in the middle of the string to perform some edit and then the caret jumps to the end of the string on the key press.
An alternative might be to change the text to upper case when the edit control loses focus.
Try here such implementation.
public MainForm()
{
InitializeComponent();
InitializeUpperCaseTextBox();
}
private void InitializeUpperCaseTextBox()
{
txtbox.CharacterCasing = CharacterCasing.Upper;
//... etc.
}
The soluttion of setting the text position to the end of the string seems like would be a hassle if you ever need to edit text that you have already entered.
It's been a while since I thought about the C# event model but, one alternative might be to catch the KeyPress event and change any lowercase KeyChar values to uppercase before passing them on to the next handler.
The way you are approaching seems to be wrong.
There are so many different ways to insert data into that textbox. What about copy & paste for instance?
Just perform a .Text.ToUpper() when accessing the value of the Textbox
Save the SelectionStart and SelectionLength before changing the text. The ToUpper should make no changes to the length, so you can simply set the SelctionStart and SelectionLength back to what they had been.
Also, I would expect to get a changed event again when you set it ToUpper. I'm not sure if you also need to check that the ToUpper actually changed anything before you set Text again. It may be smart enough to check that for you when you assign the text and avoiding giving you an infinite recursive loop of change events. However, you probably don't want to alter the selection in the event handler call for the case where you aren't making a further change, only in the outer call where you are assigning back to Text. So you might as well guard recursion directly.
Something like:
bool m_InMyTextChanged = false;
private void txtMyText_TextChanged(object sender, EventArgs e)
{
if (m_InMyTextChanged)
return; // Recursive! We can bail quickly.
m_InMyTextChanged = true; // Prevent recursion when we change it.
int selectionStart = txtMyText.SelectionStart;
int selectionLength = txtMyText.SelectionLength;
string originalText = txtMyText.Text;
string newText = originalText.ToUpper();
if (newText != originalText)
{
txtMyText.Text = newText; // Will cause a new TextChanged event.
// Set the selection back *after* the assignment, which has reset them.
txtMyText.SelectionStart = selectionStart;
txtMyText.SelectionLength = selectionLength;
}
m_InMyTextChanged = false; // Allow it for next time.
}
could work. I haven't worked in Windows Mobile, but I would think this would work the same as in general for .NET.
I figured it out. So on the textChanged event, I replace the entered text with the ToUpper version. Then I set the SelectionStart property to the Text.Length to move the cursor to the end.