I'm a starter at this so not sure if this is simple or crazly hard but what i would like is after 6 characters in a text box a - to appear and then they continue typing abit like when you do a license number in windows and it autopolutes the field as you go.
Add an event KeyPress to your textbox, so every time when you change text it will add '-' if needed. Something like this:
private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsControl(e.KeyChar) == false)
{
var tb = (sender as TextBox);
var text = tb.Text;
var blocks = text.Split('-');
var lastBlock = blocks.Last();
if (lastBlock.Length == 6)
{
tb.Text += "-";
tb.SelectionStart = tb.Text.Length;
}
}
}
There is a bug although with entering '-', as it is used as a separator.
Related
This question already has answers here:
Automatically capitalize all input in WPF
(5 answers)
Closed 5 years ago.
I want to modify the Text, that is typed in the TextBox, before it is displayed, without looking on the Text, that is already typed.
Example: xaml:
<TextBox x:Name="tb" TextChanged="tb_TextChanged">
my long text
</TextBox>
c#:
private void tb_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox tb = sender as TextBox;
if (tb != null)
{
//save caretIndex
int caretIndex = tb.CaretIndex;
//modify Text //can be any modification
//vvvvvvvvvvv Lines that I'm talking about
tb.Text.ToLower(); //or: tb.Text.ToLower(); etc.
char[] notAllowedChars = new char[] {'/t', '~', '#'}; //any other
foreach (char c in notAllowedChars)
{
tb.Text = tb.Text.Replace(c, '_'); //replace unwanted characters
}
//^^^^^^^^^^^^ these lines modify the whole text
//restore caretIndex
tb.CaretIndex = caretIndex;
}
}
In that example, the whole Text is going to be modified. But all of the other characters are already modified. So I don't want to go through them again. I want only to modify the changed text before it gets inserted.
I'm talking of 100.000+ Characters. That means, that the looking up all characters causes an unwanted performance issue.
Is there any solution or is it an impossible demand.
You can look at the TextChangedEventArgs to see the changes, and then modify the text again...here is some starting code:
private bool m_bInTextChanged;
private void tb_TextChanged(object sender, TextChangedEventArgs e)
{
if (m_bInTextChanged)
return;
m_bInTextChanged = true;
TextBox tb = sender as TextBox;
if (tb != null)
{
//save caretIndex
int caretIndex = tb.CaretIndex;
if (e.Changes.Any())
{
var addedchanges = e.Changes.Where(tc => tc.AddedLength > 0);
foreach (var added in addedchanges)
{
string stringchanged = tb.Text.Substring(added.Offset, added.AddedLength);
tb.Select(added.Offset, added.AddedLength);
tb.SelectedText = stringchanged.ToLower();
}
}
//restore caretIndex
tb.CaretIndex = caretIndex;
}
m_bInTextChanged = false;
}
I'm attempting to create a tool for supporting users on my network, basically I have a textbox that you would enter a hostname to. I'm wondering if there is a way to append a character to the text box only when a 6 digit number is entered in the box. If it's anything else, leave it alone.
Basically if the number is 123456 then put a "C" at the beginning "C123456"
but if someone already put the C in - don't do anything.
Also there would be other characters (for other hostnames) that I would not want changed. Only if 6 digits are entered, to put a "c" in front.
Sample code:
This is what i have so far:
private void IPfind(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
TextBox tb = (TextBox)sender;
string text = tb.Text.ToUpper();
int num;
if (int.TryParse(text, out num))
{
// it is an integer. Simply add a C at the begining if it has enough characters
if (text.Length == 6)
{
tb.Text = 'C' + text;
tb.CaretIndex = tb.Text.Length;
}
else
{
}
Ipbox.Clear();
try
{
// Host Name resolution to IP
IPHostEntry host = Dns.GetHostEntry(Assetbox.Text.Trim());
IPAddress[] ipaddr = host.AddressList;
// Loop through the IP Address array and add the IP address
foreach (IPAddress addr in ipaddr)
{
// Finds the IP V4 address
if (addr.AddressFamily == AddressFamily.InterNetwork)
Ipbox.Text = (addr.ToString());
}
}
Use if blocks to check everything. I explain different parts in comments:
bool _changing = false; // since you are going to change Text you need this to stop a loop or other errors
private void Tb_TextChanged(object sender, TextChangedEventArgs e)
{
if (_changing)
return;
_changing = true;
TextBox tb = (TextBox)sender;
string text = tb.Text.ToUpper();
if (text == null || text.Length == 0)
{
// The user has not enter enough characters yet
return;
}
int num;
if (int.TryParse(text, out num))
{
// it is an integer. Simply add a C at the begining if it has enough characters
if (text.Length == 6)
{
tb.Text = 'C' + text;
tb.CaretIndex = tb.Text.Length;
}
else
{
// let use to continue typing
}
}
else
{
// it is not an integer
//check if it starts with P or C
if (text[0] == 'C' || text[0] == 'P')
{
string textrest = text.Remove(0, 1);
if (textrest.Length == 0)
{
// it is just a C or P
return;
}
if (int.TryParse(textrest, out num))
{
// it became an integer after removing the first char. It is OK then.
}
else
{
// it is not a number and removing the first C or P did not solve the problem
// throw new FormatException();
// or
MessageBox.Show("Wrong Format. Enter ###### or C###### or P#######");
}
}
else
{
// it is not a number and the reason is not because it starts with C or P
// throw new FormatException();
// or
MessageBox.Show("Wrong Format. Enter ###### or C###### or P#######");
}
}
_changing = false;
}
So I think Regex could be really useful here,
make your textbox then make a textchanged event like so in the XAMl,
<TextBox x:Name="textBox" TextChanged="textBox_TextChanged"/>
Then in C#(code behind), you can add the code to the event,
private void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
var pattern = new Regex(#"(\w[0-9]{6})"); //This is a regex pattern, you can make it much more intelligent, like if you just want P or C chars to accepted rather than any letter
var isThereMatch = pattern.Match(textBox.Text); // Is there a match?
string strThingIwannaSAVE = isThereMatch.ToString(); //If there is save that string so you can manipulate it
if (textBox.Text.Length > 6) //only execute the following code if you have enough characted in your box
{
if (string.IsNullOrWhiteSpace(strThingIwannaSAVE)) //if there is no match or its just whitespaces for some reason, empty out your box or display a message or whatever else
{
MessageBox.Show("Wrong input");
textBox.Text = String.Empty;
}
else
{
//String is good, add it to a database? do something to it?
}
}
}
EDIT
If you want to just match P or C characters plus the numbers, make two regex patterns,
var pattern = new Regex(#"(c{1}[0-9]{6})");
var pattern2 = new Regex(#"(p{1}[0-9]{6})");
Then check textbox for matches
Thanks huge to both #JohnChris and #Ramin
I used both solutions to fix this
TextBox tb = (TextBox)sender;
string text = tb.Text;
if (Regex.IsMatch(text, #"^\d+$") && text.Length == 6)
{
tb.Text = 'C' + text;
tb.CaretIndex = tb.Text.Length;
}
I tried to get textboxes to only allow numbers and a hyphen declaring a negative number however i researched and tried to replicate what i found and it doesn't work. maybe im missing something but i have no clue about Regex so maybe its wrong. but it doesn't update and accepts letters and other characters
Regex reg = new Regex(#"^[0-9-]*$");
bool textChangedByKey;
string lastText;
private void Team1Q1_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox senderTB = sender as TextBox;
if (char.IsControl(e.KeyChar)) return;
if (!reg.IsMatch(senderTB.Text.Insert(senderTB.SelectionStart, e.KeyChar.ToString()) + "1"))
{
e.Handled = true;
return;
}
textChangedByKey = true;
}
private void Team1Q1_TextChanged(object sender, EventArgs e)
{
OnTeamInfoChanged();
TextBox senderTB = sender as TextBox;
if (!textChangedByKey)
{
if (!reg.IsMatch(senderTB.Text))
{
return;
}
}
else
{
textChangedByKey = false;
lastText = senderTB.Text;
}
}
Changing the Regex pattern to ^-?[0-9]*$ would only allow a single hyphen, and only at the start of the input.
Wiring up the KeyPress event handler in the designer class like so should cause disallowed characters to get filtered out:
this.Team1Q1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Team1Q1_KeyPress);`
I would like to modify the default behavior of a regular WinForms C# textbox control so that pressing backspace deletes whole words instead of just a single character.
Ideally I would like to have this special behavior only when the caret position is in-front of a white-space character. For example; pressing backspace one time when the caret is at "hello world|" should still only remove one character resulting in "hello worl|" - but if the caret is at "hello world |" when I press backspace, then the result should be "hello |"
First you need to add KeyEventHandler for KeyDown event for your TextBox
this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.textBox1_KeyDown);
After that you can handle the event like this:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
TextBox t = (TextBox)sender;
if (e.KeyCode == Keys.Back)
{
int carretIndex = t.SelectionStart;
if (carretIndex>0 && carretIndex == t.Text.Length && t.Text[carretIndex-1] == ' ')
{
int lastWordIndex = t.Text.Substring(0, t.Text.Length - 1).LastIndexOf(' ');
if (lastWordIndex >= 0)
{
t.Text = t.Text.Remove(lastWordIndex + 1);
t.Select(t.Text.Length, 0);
}
else
{
t.Text = string.Empty;
}
}
}
}
Take a look at the keypress/keydown events.
Here you go, I tested it out and it works fine:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
String[] chars = new String[1]{" "};
if(e.KeyValue == 8)
{
var temp = (from string s in textBox1.Text.Split(chars, StringSplitOptions.None)
select s).ToArray();
temp[temp.Length-1] = "";
textBox1.Text = String.Join(" ",temp).ToString();
SendKeys.Send("{END}");
}
}
Its a psuedo code, I hope you will find it helpful:
// check backspace is pressed
if keycode==keycode(backspace) then
// testing cursor is just after space(113) character
if string[string length] == keycode(space) then
// loop through string in reverse order
loop each character in reverse
// start removing each character
remove the characters
till find 2nd space
end if
end if
I am working with some electronics instruments using GPIB. I can communicate with instruments like this:
K2400.WriteString("*IDN?", true);
textBoxK2400.Text += K2400.ReadString() + Environment.NewLine;
The first line will execute a command, and in the second line I add the response of the last command to the textbox. How can I write the command in the textbox directly and add the response?
For example, if the user command entered after an indicator like ">>" and hitting ENTER, the response should be added in the next line of textbox.
So how can I read the last line of a textbox and add the respone in a new line? I am looking for a method like:
private void Execute(string command)
{
K2400.WriteString(command, true);
textBoxK2400.Text += K2400.ReadString() + Environment.NewLine;
}
Use two Text boxes(textbox and a listbox might be better) but make them look as "one" textbox.. If using WPF it could look pretty nice and in Windows form possible at least.
Did a quick test..
And with this code for KeyPress event for the textbox:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return)
{
listBox1.Items.Add(textBox1.Text);
textBox1.Text = String.Empty;
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}
}
You could try this:
private void textBoxK2400_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return)
{
string command = textBoxK2400.Text.Split('\n').LastOrDefault();
if (!String.IsNullOrEmpty(command) && command.StartsWith(">>"))
{
K2400.WriteString(command.Substring(2), true);
textBoxK2400.Text += K2400.ReadString() + Environment.NewLine;
textBoxK2400.Text += ">>"; // It's not necessary
}
}
}
private void Execute(string command) { K2400.WriteString(command,
true); textBoxK2400.Text += K2400.ReadString() + Environment.NewLine;
}
this is it. I'd just recommend to 'buffer' a part of the text, not all, because it could be long by the end. You can split it to lines before and take a number of lines (i. e. 10).
And don't forget to make the field black and the text green, it looks much more professional when the command field is decorated such way.
Well first i would suggest a RichTextBox to use.
To capture ENTER you should use KeyPress Event .
private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
string LastLine = richTextBox1.Lines[richTextBox1.Lines.Length-2];
if (LastLine.StartsWith(">>"))
{
//here you can filter the LastLine
K2400.WriteString(LastLine, true);
richTextBox1.AppendText(K2400.ReadString() + Environment.NewLine);
}
else
{
//here you can unwrite the last line
string[] totalLines = richTextBox1.Lines;
richTextBox1.Text = "";
for (int i = 0; i < totalLines.Length - 2; i++)
{
richTextBox1.AppendText(totalLines[i]+Environment.NewLine);
}
MessageBox.Show("That was not a valid command");
}
}
}