Set specific text to bold in WPF RichTextBox - c#

I am extending the functionality of a WPF Richtextbox. I want certain text to become bold when I type it in. I was able to get certain text to bold but the text following the bolded word would also become bolded...
Heres a sample of my code:
private bool _Running = false;
void CustomRichTextBox_TextChange(object sender, TextChangedEventArgs e)
{
if(_Running)
return;
_Running = true;
//Logic to see if text detected
//Logic to get TextPointers
//Logic to get TextRange
var boldMe = new TextRange(textPointer1, textPointer2);
//Bold text
boldMe.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
_Running = false;
}
I want:
NOTBOLDED NOTBOLDED BOLDED NOTBOLDED
but what I get:
NOTBOLDED NOTBOLDED BOLDED NOTBOLDED
**Please note that it becomes bolded while typing.
How do I prevent the text after a bolded word from also becoming bolded?
Not duplicate question since the accepted solution for provided link is for WinForms and the rest are for preset text.

After several tests, I figured out a simple solution.
CaretPosition = CaretPosition.GetPositionAtOffset(0, LogicalDirection.Forward);
This set caret in the right orientation, preventing the BOLD setting from continuing within the Run object.
if(textPointerEnd.GetNextInsertionPosition(LogicalDirection.Forward) == null)
new Run("", textPointerEnd);
This would add a Run object to the end of a new Bold object that was located at the end of the Paragraph object.

You will need to detect when your required text is no longer detected, probably if a space occurs, then remove the bolding value and reset it back to normal.

Related

C# Masked textbox with date format skips first character

I have a problem in a winform app.
I have several masked textbox which use the short date mask (//____), the problem is that if I select all the text (either with Ctrl + a or from code) and I write a new date is like that the first character goes at an 11th position (the mask disappear and i see only the character I wrote) and if I press backspace the text becomes something like this _1/01/1979 and I have to select all again and press backspace or delete everything.
I handled in this way
private void maskedTxt_KeyPress(object sender, KeyPressEventArgs e)
{
MaskedTextBox msk = sender as MaskedTextBox;
if (msk != null)
{
if (!string.IsNullOrEmpty(msk.Text.Replace("/", string.Empty).Replace(":", string.Empty).Trim()) && _focused)
{
_focused = false;
SendKeys.SendWait("{BACKSPACE}");
}
}
}
_focused is a Boolean variable that I set to true if a validation error happens at the leave event of the masked textbox (invalid date, the date is too big or too small etc...)
so that when someone enters the textbox the text can be written correctly
Is there a better way to handle this "error" or this is good? I tried it and it worked but a lot of people will have to use this application and probably there will be some errors along the way.
Thanks

WPF RichTextBox - Remove text formatting on paste and move caret properly

I am having trouble removing the formatting (bold, font, size etc.) on paste of some formatted text into a RichTextBox.
I have successfully been using the following:
Add a pasting handler to the RichTextBox
DataObject.AddPastingHandler(RichTextBoxControl, TextBoxPasting);
Remove formatting and insert text
private void TextBoxPasting(object sender, DataObjectPastingEventArgs e)
{
var pastingText = e.DataObject.GetData(DataFormats.Text) as string;
RichTextBoxControl.Document.ContentEnd.InsertTextInRun(pastingText);
e.CancelCommand();
}
But unfortunately this always places the inserted text in the end of the RichTextBox. Also the caret is not moving.
Let us say you are at this positing:
Helloꕯ World and you are pasting Beautiful you would get Helloꕯ World Beutiful instead of Hello Beutifulꕯ World.
Instead of manually inserting the text and cancelling the event you could just alter the text that is to be inserted in the DataObjectPastingEventArgs, and let the chains of the event do all the work for you.
private static void TextBoxPasting(object sender, DataObjectPastingEventArgs e)
{
e.DataObject = new DataObject(DataFormats.Text, e.DataObject.GetData(DataFormats.Text) as string ?? string.Empty);
}
e.DataObject.GetData(DataFormats.Text) is getting you the plain text without any formatting. The caret will move properly since you are not canceling the events that were supposed to move it.

How can I copy a line from a Richtextbox when I select it?

I am trying to automatically highlight and copy a single line from a rich text box and store it in a variable when I click on any part of the line.
Is this possible?
The Click event and something like the following should help:
private void richTextBox1_Click(object sender, EventArgs e)
{
int index = richTextBox1.SelectionStart;
int line = richTextBox1.GetLineFromCharIndex(index);
string lineText = (richTextBox1.Lines.Length > 0) ? richTextBox1.Lines[line] : "";
//Debug output for my own testing purposes
Debug.WriteLine(lineText);
}
You may want to do something different when the RichTextBox is empty. I just use an empty string.
Here's an example of the output from a simple app:
The text show in the output window reflects the order in which I clicked the lines after typing.
However, one caveat to this is that you don't need to click exactly on the line for it to count. For example, clicking in the empty space below the last line registers as clicking the last line, because that's where the cursor ends up. It might not matter a whole lot, but it's something to be aware of.

How to get a textbox to only display Uppercase letters?

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.

How do I highlight a selection made programmatically in a Winforms TextBox

I've not gone into much research here, but the intuitive thing is not working:
private void SerachButton1_Click(object sender, EventArgs e)
{
String serchTerm = searchTerm1.Text;
String text = usualTextBox.Text;
Int32 index = text.IndexOf(serchTerm);
if (index >= 0)
{
usualTextBox.Select(index, serchTerm.Length);
}
}
SelectedText, SelectionLength and SelectionStart properties are as I expect them after Select is called but there's no visible selection.
What am I doing wrong here?
Edit: I've also tried RichTextBox. When I set background and text colors for the selection it shows up, but it won't unselect automatically when you manually select another part of text or just click on a position in text. Are these two types of selection inherently different and if you select programmatically you have to also deselect programmatically?
You need to set usualTextBox.HideSelection to false so that the selection remains visible when the focus is not in the TextBox.

Categories