Reputation: 527
Basically, I have keywords like sin(
and cos(
in a textbox, which I want to have behave like a single character.
When I mention the entire string below it is referring to the group of characters (for example "sin(
")
Using sin(
as an example:
If the caret was in this position (behind the s
):
If you pressed del
, it would remove the entire string. If the right arrow key was pressed the caret would jump to after the (
.
If the caret was in this position (after the (
):
If backspace
was pressed, the entire string would be removed. If the left arrow key was pressed, the caret would jump to behind the s
.
EDIT: Thanks to John Skeet who pointed this out.
Selecting any substring of the group of characters (for example si
from sin(
) should select the entire string.
Sorry if it is difficult to understand, what I have in mind is a bit difficult to put into words.
EDIT 2: Thanks to Darksheao for providing me the answer for the backspace and delete keys. I relocated the delete
segment to the PreviewKeyDown event, as it does not work with the KeyPress Event.
EDIT 3: Using the charCombinations
way of doing things, here is how I did the implementation for the left and right keys:
#region Right
case Keys.Right:
{
s = txt.Substring(caretLocation);
foreach (string combo in charCombinations)
{
if (s.StartsWith(combo))
{
textBox1.SelectionStart = caretLocation + combo.Length - 1;
break;
}
}
break;
}
#endregion
#region Left
case Keys.Left:
{
s = txt.Substring(0, caretLocation);
foreach (string combo in charCombinations)
{
if (s.EndsWith(combo))
{
textBox1.SelectionStart = caretLocation - combo.Length + 1;
break;
}
}
break;
}
#endregion
All that remains is the mouse implementation. Anyone? I also realised that the user may use the mouse to place the caret in the middle of one of these strings, so when that happens the mouse needs to be moved to the start of the string.
Upvotes: 8
Views: 515
Reputation: 114
Here is a section of code that sets up an array of the character combinations that you want to be seen as "single characters" and sets up a handler that looks for them.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
string[] charCombinations = new string[2];
charCombinations[0] = "sin(";
charCombinations[1] = "cos(";
string txt = this.textBox1.Text;
int caretLocation = this.textBox1.SelectionStart;
if (e.KeyCode == Keys.Delete)
{
//get text in front
string s = txt.Substring(caretLocation);
string notChecking = txt.Substring(0, caretLocation);
foreach (string combo in charCombinations)
{
if (s.StartsWith(combo))
{
txt = notChecking + s.Substring(combo.Length - 1);
break;
}
}
}
if (e.KeyCode == Keys.Back)
{
//get text in behind
string s = txt.Substring(0, caretLocation);
string notChecking = txt.Substring(caretLocation);
foreach (string combo in charCombinations)
{
if (s.EndsWith(combo))
{
txt = s.Substring(0, s.Length - combo.Length + 1) + notChecking;
caretLocation -= combo.Length - 1;
break;
}
}
}
this.textBox1.Text = txt;
//changing the txt feild will reset caret location
this.textBox1.SelectionStart = caretLocation;
}
Making some modifications to this so that you are searching around the SelectionStart will handle what was mentioned in Jon's comment.
References: TextBox Event Reference and How do I find the position of a cursor in a text box? C#
Upvotes: 2