RichTextBox inserting text - c#

For Windows Forms.
I am trying to insert text into the .rtf field of a RichTextBox.
I have tried two methods. When I use .Rtf.insert, nothing happens at all.
When I edit the .rtf string based on the selected text positions myself, I either end up adding gibberish to the thing or getting an error that says that the file format is invalid. My best guess is that this is because the .rtf string is in .rtf format and the selection index that I am using is based on the plain text string and so I am inserting the text in the wrong location in the .rtf string and messing up the RTF code.
But knowing what the problem is (if I am correct) hasn't helped me solve it.
Is there a way to get .rtf.insert to work correctly, or is there a way to translate the selected text indexes to the actual .rtf text positions so that something like the code below would work? I am assuming that the RichTextBox itself must know how to translate the one index into another because it can insert characters when the user types just fine.
Here is my code snippet. The point of the code is to insert a marker into the text that will later be parsed and replaced with a student's first name. There will be other such codes. "codeLeader" and "codeEnder" are just the strings I use to surround the codes with. In this case I am using "[*" and *]" to indicate that there is a code I will need to parse, but I put them into separate strings so that I can easily change it if I wish. I have actually already written the parsing code, which works just fine on rich text. It is just inserting the text into the richTextBox itself that is the problem. In other words, if I were to type the codes by hand it would work just fine. But this would be troublesome for the user because some of the codes will use index numbers.
private void studentFirstNameCode_Click(object sender, EventArgs e)
{
string ins = f1ref.codeLeader;
ins += "SNFirst" + f1ref.codeEnder;
int start = editorField.richTextBox1.SelectionStart;
if (start == -1) { start = 0; }
int end = start + editorField.richTextBox1.SelectionLength;
if (end == -1) { end = 0; }
string pre = editorField.richTextBox1.Rtf.Substring(0, start);
string post = editorField.richTextBox1.Rtf.Substring(end);
string newstring = pre + ins + post;
editorField.richTextBox1.Rtf = newstring;
// this also doesn't work. gives no result at all.
// editorField.richTextBox1.Rtf.Insert(start, newstring);
}

I don't think that you need to use the RTF property to simple insert a text inside the RichTextBox actual text. In particular because you don't seem to add an RTF formatted text.
If you don't want to use RTF then the simplest way to accomplish your goal is just one line of code
editorField.SelectedText = yourParameterText;
This will work as you have pasted the text from the clipboard in the selected position (eventually replacing text if something is selected) and the base work of correctly formatting your text inside the RTF is done by the control itself

I have found a work-around by using .SendKeys. This makes the text appear a bit slowly (as if typed very quickly) so isn't optimal, but it does work.
It is enough for a workable solution, but I am still troubled by the problem. It seems like this issue should have a more elegant solution than this.

Related

Is there a way to bridge empty lines with Substring?

With the following code, I delete line by line in a TextBox (0, 39). Now there is on the last place a money amount (1 any Articel 10.00) which I want to deduct from the total amount. For that, I use the Substring. But there I get errors, as probably the empty spaces are not interpreted. Is there a simple solution to this? Thanks
private void btnDelete_Click(object sender, EventArgs e)
{
if (TextBox1.Text.Length > 0)
{
txtTotal.Text = (Double.Parse(txtTotal.Text) - Double.Parse(TextBox1.Text.Substring(8, 2))).ToString("0.00");
TextBox1.Text = TextBox1.Text.Remove(0, 39);
}
if (TextBox1.Text.Length == 0)
{
MessageBox.Show("The cart is empty");
Few things you can do to make your life easier (assuming you have to keep a TextBox as you have stated to others.)
Before I get into the details however, the issue seems to be you're having trouble parsing text that represents lines of data, data which contains amounts which you want to act on. If this is an incorrect assumption, disregard this answer.
Ok, back to it...
Rather than trying to work with the text directly in the TextBox, start by reading in your entire string as a list of lines (i.e. List<String>). You can do that with the Split function or with RegEx expressions. See here
Use RegEx expressions for each line to identify not just the type of line it is (an 'item' line or the 'All' line at the bottom) as well as the various parts of those lines. For instance, you can use a RegEx that starts at the end of the line and goes backwards looking for a number (in the form of a string.) Use the result of that for your Parse method to get the actual numeric value.
Finally, if you still need to remove the lines of text (I'm not sure if you're removing the text just for your logic or if you need to display it) simply remove them from your list of strings for the lines. If it needs to be displayed back in the UI (doubtful as it seems it should be blank at the end of processing) just use Join to convert the lines back to a string, then set that back to the TextBox.Text property.
Hope this helps!
Mark
P.S. To (try and) avoid comments such as the ones you got about your design, it may help to start your question by saying something like 'Unfortunately I'm restricted to using a TextBox due to issues outside of this question, hence I'm looking for an answer here.' At least that should cut back on those responses telling you to 'Do it differently!' instead of answering your question.

(WinRT)How to get TextBox caret index?

I got some problems with getting caret index of TextBox in Windows Store App(WP 8.1).
I need to insert specific symbols to the text when button is pressed.
I tried this:
text.Text = text.Text.Insert(text.SelectionStart, "~");
But this code inserts symbol to the beginning of text, not to the place where caret is.
UPDATE
I updated my code thanks to Ladi. But now I got another problem: I'm building HMTL editor app so my default TextBlock.Text is: <!DOCTYPE html>\r\n<html>\r\n<head>\r\n</head>\r\n<body>\r\n</body>\r\n</html>
So for example when user inserts symbol to line 3, symbol is inserted 2 symbols before caret; 3 syms before when caret is in line 4 and so on. Inserting works properly when symbol is inserted to the first line.
Here's my inserting code:
Index = HTMLBox.SelectionStart;
HTMLBox.Text = HTMLBox.Text.Insert(Index, (sender as AppBarButton).Label);
HTMLBox.Focus(Windows.UI.Xaml.FocusState.Keyboard);
HTMLBox.Select(Index+1,0);
So how to solve this? I guess new line chars making trouble.
For your first issue I assume you changed the TextBox.Text before accessing SelectionStart. When you set the text.Text, text.SelectionStart is reset to 0.
Regarding your second issue related to new lines.
You could say that what you observe is by design. SelectionStart will count one "\r\n" as one character for reasons explained here (see Remarks section). On the other hand, method string.Insert does not care about that aspect and counts "\r\n" as two characters.
You need to change slightly your code. You cannot use the value of SelectionStart as the insert position. You need to calculate the insert position accounting for this behavior of SelectionStart.
Here is a verbose code sample with a potential solution.
// normalizedText will allow you to separate the text before
// the caret even without knowing how many new line characters you have.
string normalizedText = text.Text.Replace("\r\n", "\n");
string textBeforeCaret = normalizedText.Substring(0, text.SelectionStart);
// Now that you have the text before the caret you can count the new lines.
// that need to be accounted for.
int newLineCount = textBeforeCaret.Count(c => c == '\n');
// Knowing the new lines you can calculate the insert position.
int insertPosition = text.SelectionStart + newLineCount;
text.Text = text.Text.Insert(insertPosition, "~");
Also you should make sure that SelectionStart does not exhibit similar behavior with other combinations beside "\r\n". If it does you will need to update the code above.

Match.Value and international characters

UPDATE May this post be helpful for coders using RichTextBoxes. The Match is correct for a normal string, I did not see this AND I did not see that "ä" transforms to "\e4r" in the richTextBox.Rtf! So the Match.Value is correct - human error.
A RegEx finds the correct text but Match.Value is wrong because it replaces the german "ä" with "\'e4"!
Let example_text = "Primär-ABC" and lets use the following code
String example_text = "<em>Primär-ABC</em>";
Regex em = new Regex(#"<em>[^<]*</em>" );
Match emMatch = em.Match(example_text); //Works!
Match emMatch = em.Match(richtextBox.RTF); //Fails!
while (emMatch.Success)
{
string matchValue = emMatch.Value;
Foo(matchValue) ...
}
then the emMatch.Value returns "Prim\'e4r-ABC" instead of "Primär-ABC".
The German ä transforms to \'e4!
Because I want to work with the exact string, i would need
emMatch.Value to be Primär-ABC - how do I achieve that?
In what context are you doing this?
string example_text = "<em>Ich bin ein Bärliner</em>";
Regex em = new Regex(#"<em>[^<]*</em>" );
Match emMatch = em.Match(example_text);
while (emMatch.Success)
{
Console.WriteLine(emMatch.Value);
emMatch = emMatch.NextMatch();
}
This outputs <em>Ich bin ein Bärliner</em> in my console
The problem probably isn't that you're getting the wrong value back, it's that you're getting a representation of the value that isn't displayed correctly. This can depend on a lot of things. Try writing the value to a text file using UTF8 encoding and see if it still is incorrect.
Edit: Right. The thing is that you are getting the text from a WinForms RichTextBox using the Rtf property. This will not return the text as is, but will return the RTF representation of the text. RTF is not plain text, it's a markup format to display rich text. If you open an RTF document in e.g. Notepad you will see that it has a lot of weird codes in it - including \'e4 for every 'ä' in your RTF document. If you would've used some markup (like bold text, color etc) in the RTF box, the .Rtf property would return that code as well, looking something like {\rtlch\fcs1 \af31507 \ltrch\fcs0 \cf6\insrsid15946317\charrsid15946317 test}
So use the .Text property instead. It will return the actual plain text.

RichTextBox: Find corresponding index

Say I have a WPF RichTextBox with the following content:
Hello Hello // <== here is a line break \r\n
Turn Your Radio On!
I then read the text from the box with the following code:
public static string GetText(this RichTextBox box)
{
var range = new TextRange(box.Document.ContentStart,
box.Document.ContentEnd);
return range.Text;
}
After that I retrieve var index = text.IndexOf("Hello\r\nTurn") and var length = "Hello\r\nTurn".Length.
Based on index and length:
How can I select that text in the RichTextBox? The index/length in the plain string does not match up with what the RichTextBox expects.
I tried the approach from the answer here, but this does not seem to work if the text contains a line wrap / paragraph.
Note: My string manipulation (finding index / length) is considerably more complex than the example, but the example given here describes my problem well
The RichTextBox has a Selection property that you can call its "Select" method.
It accepts 2 TextPointer objects, one for the selection start and the other for its end.
http://msdn.microsoft.com/en-us/library/system.windows.documents.textrange.select.aspx
I don't think you the index and length properties will be good enough for you to select the text. You would have to get the real TextPointer.
Try using a method for finding specific words TextPointers such as the one specified in here -
http://blogs.microsoft.co.il/blogs/tamir/archive/2006/12/14/RichTextBox-syntax-highlighting.aspx

C# Unknown Text Found

I'm creating a program to transfer text from a word document to a database. During some testing I came across some text inside a textbox after setting it's text to a table cell range as follows:
textBox1.Text = oDoc.Tables[1].Cell(1, 3).Range.Text;
What appeared in the form was:
What wasn't expected was the dot at the end of the text and I have no idea what it is supposed to represent. The dot can be highlighted but if you try and copy and paste it nothing appears. You can delete the dot manually. Can anyone help me identify what this is?
The identification bit shouldn't be too hard:
string text = oDoc.Tables[1].Cell(1, 3).Range.Text;
textBox1.Text = ((int) text[4]).ToString("x4");
That will give you the Unicode UTF-16 code unit for that character... you can then find out what it is on the Unicode web site. (I usually look at the Charts page or the directory of PDFs and guess which chart it will be in based on the numbering - it's not ideal, and there are probably better ways, but it's always worked well enough for me...)
Of course when you've identified it you'll still need to work out what the heck it's doing there... does the original Word document just have "HOLD"?

Categories