I am using RichEditBox for a rich text editor: I use different colors for different keywords in the text while user types the text in the richEditBox control.
Before making changes I save current selection position:
ITextSelection selection = richEditBox.Document.Selection;
int originalStartPosition = selection.StartPosition;
int originalEndPosition = selection.EndPosition;
then I change color of some parts of the text, for example:
selection.SetRange(startIndex, stopIndex);
selection.CharacterFormat.ForegroundColor = Colors.Red;
and after making all changes I restore current selection position:
selection.SetRange(originalStartPosition, originalEndPosition);
This works fine, but SetRange() function affects scrolling position of the text in richEditBox, because it automatically scrolls to make the selected part of the text visible on the screen. So, after all color modifications the scroll position of richEditBox control becomes modified.
Final SetRange() function call puts cursor in its initial place, but not the scroll position.
So, my question is: how can I restore scrolling position of richEditBox control after making color changes? Or how can I modify text color without affecting the scroll position?
It seems it is by design. When we set the cursor in the RichEditBox, then we can scroll the text that we can not see the cursor. After we use the SetRange method, it will scroll to the position that we set the cursor. If the cursor is in the view, it will not scroll.
If you want to scroll to the text range that you set, you should be able to set the PointOptions.Start to the ScrollIntoView method. It will scroll the end of the text range into view.
For example:
ITextSelection selection = MyRichEditBox.Document.Selection;
int originalStartPosition = selection.StartPosition;
int originalEndPosition = selection.EndPosition;
selection.SetRange(600, 610);
selection.CharacterFormat.ForegroundColor = Colors.Red;
selection.SetRange(originalStartPosition, originalEndPosition);
selection.ScrollIntoView(PointOptions.Start);
Edit code:
ITextSelection selection = MyRichEditBox.Document.Selection;
int originalStartPosition = selection.StartPosition;
int originalEndPosition = selection.EndPosition;
selection.SetRange(600, 610);
selection.ScrollIntoView(PointOptions.Start);
await Task.Delay(2000);
selection.CharacterFormat.ForegroundColor = Colors.Red;
selection.SetRange(originalStartPosition, originalEndPosition);
Related
I'm using C# with WPF, to draw some graphics and texts into a WPF Canvas.
For adding texts to the canvas I use a TextBlock and this works fine when I don't change the size of the Canvas.
When I extend the width of the canvas, sometimes the text is not drawn (from the x-position where I extended the canvas). The text is there, because I can see the text background (and also a strikethrough which I added for testing).
When I change the length of the text and/or set the TextBlock length in code, the behavior changes. Meaning with some changes the text is shown.
The graphics are shown just fine in all circumstances.
I've tried to make sure the Width and ActualWidth of the Canvas are correct before I draw the texts.
I use this code to draw the text onto the Canvas:
private void drawHeartrate(string hr, double xHr)
{
TextBlock hrTextBlock = new TextBlock();
hrTextBlock.Text = hr;
hrTextBlock.Foreground = Brushes.Black;
hrTextBlock.TextDecorations = TextDecorations.Strikethrough;
hrTextBlock.Background = Brushes.Yellow;
hrTextBlock.FontFamily = new FontFamily("Soho Gothic Pro");
hrTextBlock.FontSize = 14;
Canvas.SetLeft(hrTextBlock, xHr);
Canvas.SetTop(hrTextBlock, -2);
CnvsEcg.Children.Add(hrTextBlock);
}
The screen where the texts is not displayed anymore looks like this (from the above code):
Screenshot of problem text
I want to have a textblock with the user's name and right at the end of the string, an image to click and edit the name.
Since I can't control the name's length and I want it to follow the input string to the last character, I need to figure the width or the right border point of the text block.
I've tried Width (NaN) and ActualWidth (always 0) after setting the Text property, but it didn't work (tried UpdateLayout() as well).
The text is left aligned to another element so I can't right-align it.
How can I get the position of the right most part of the textblock with a dynamically input text in either code or XAML?
You can use ActualWidth property to get the width of TextBlock. But right after setting Text, the ActualWidth will not be updated immediately. One solution is to listen changes on ActualWidth of that TextBlock, and you will get the right value whenever it's changed
public MainWindow()
{
InitializeComponent();
DependencyPropertyDescriptor.FromProperty(TextBlock.ActualWidthProperty, typeof(TextBlock))
.AddValueChanged(textBlock1, (s, e) =>
{
var yourExpecedWidth = textBlock1.ActualWidth;
});
}
I have been watching a couple of videos and I've noticed that you can highlight or set the BackColor for every word it finds in a RichTextBox, I tried doing this with a Label which is what I'm working with on my project but I can't use Label.Find and Label.SelectionBackColor etc. Is there a way I could search a word in my label and highlight it?
You cannot use two different foreground/background colors in a label. You might split up the text in different labels or just use a richtextbox.
Here is a workaround, create a RichTextBox and use it as a label.
Set these properties to make it look like a label:
richTextBox.ReadOnly = true;
richTextBox.BorderStyle = BorderStyle.None;
richTextBox.BackColor = SystemColors.Control; // or whatever your background color is
work around to disable User selection:
richTextBox.Enabled = false;
richTextBox.SelectAll();
richTextBox.SelectionColor = SystemColors.ControlText; // or whatever you want the default text color to be
// you have to set the color or else it will be gray because of Enabled=false
Edit: i just tried it, after SelectAll(); and SelectionColor = SystemColors.ControlText any changing or adding of Text keeps it black (unless the current SelectionStart is at a point of the text where the color is different
I have a path selector in my Visual C# Express 2010 form application.
I do it using a FolderBrowserDialog and a (single line) TextBox, to show the selected path. Using the following line in my UI refresh code.
this.textBoxFolder.Text = this.folderBrowserDialog1.SelectedPath;
The ReadOnly property is set to true and TextAlign property is set to Right using the form designer, because the selected path is often longer than the TextBox, and I prefer to show the right-side of the path. The forms designer generates this:
//
// textBoxFolder
//
this.textBoxFolder.Location = new System.Drawing.Point(40, 72);
this.textBoxFolder.Name = "textBoxFolder";
this.textBoxFolder.ReadOnly = true;
this.textBoxFolder.Size = new System.Drawing.Size(160, 20);
this.textBoxFolder.TabIndex = 13;
this.textBoxFolder.TabStop = false;
this.textBoxFolder.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
Whenever the chosen path is shorter than the textbox size, the Right alignment works. (But this is not really important)
Whenever the chosen path is longer than the textbox size, the Right alignment has no effect, the string in the textbox is displayed such that the left-most character is visible, and right-most are hidden.
I know that in a normal single line TextBox (ReadOnly = false), when an overly-long string is typed in by hand, the right most chars are visible, even when focus goes away, regardless of whether TextAlign is set to Left / Right / Center!
In other words, my goal is, when TextBox.Text is programmatically set (as opposed to typed in), and the string is longer than the width of the TextBox, how do I get the right-most chars to be visible?
Instead of setting the TextAlign property, you should move the caret to the last character:
textBoxFolder.Text = this.folderBrowserDialog1.SelectedPath;
textBoxFolder.SelectionStart = textBox1.Text.Length - 1;
Setting SelectionStart actually moves the caret to the specified position. And that makes the character at that position visible in the TextBox.
If you can use a Label instead of a text box, you can use the one created by Hans Passant here that uses TextFormatFlags.PathEllipses flag while drawing the text.
Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows CE Platform Note: In Pocket PC-based applications, a single-line text box supports only left alignment. A multiline text box can be aligned on the left, right, or center.
I have a C# Windows Forms program that has a RichTextBox control. Whenever the text inside the box is changed (other than typing that change), the cursor goes back to the beginning.
In other words, when the text in the RichTextBox is changed by using the Text property, it makes the cursor jump back.
How can I keep the cursor in the same position or move it along with the edited text?
Thanks
You can store the cursor position before making the change, and then restore it afterwards:
int i = richTextBox1.SelectionStart;
richTextBox1.Text += "foo";
richTextBox1.SelectionStart = i;
You might also want to do the same with SelectionLength if you don't want to remove the highlight. Note that this might cause strange behaviour if the inserted text is inside the selection. Then you will need to extend the selection to include the length of the inserted text.
Be careful, if someone refreshes or changes totally the RichTextBox content, the focus method must be invoqued previously in order to move the caret:
richTextBox1.Focus();
int i = richTextBox1.SelectionStart;
richTextBox1.Text = strPreviousBuffer;
richTextBox1.SelectionStart = i;
here's a smaller one, that has the same effect. this.richTextBox1.Select(this.richTextBox1.Text.Length, 0);
That marks 0 chars at the end of the text and sets the cursor to end