Hide some part of text in the Richtextbox in vb.net - winforms

I want to hide some part of text in the richtextbox in vb.net.
i.e.
Richtextbox1.text ="Test1 test2 test3"
Now i want to hide "test2" from richtextbox text and it should display only "Test1 test3" text on the richtextbox control.
So anyone help me and tell me how to do that?
Thanks in Advance.

The RichTextBox control does support the Visible rtf codes, so this would work:
string hideText = "test2 ";
if (richTextBox1.Find(hideText) > -1) {
richTextBox1.SelectedRtf = #"{\rtf1\ansi\v " + hideText + #"\v0}";
MessageBox.Show(richTextBox1.Text);
}
Note that the message displayed will still show "test2".
Per your comment, here is a method to hide all instances of a word by iterating backwards:
string hideText = "[test2]";
int index = richTextBox1.TextLength;
while (index > -1) {
index = richTextBox1.Text.LastIndexOf(hideText, index);
if (index > -1) {
richTextBox1.Select(index, hideText.Length);
richTextBox1.SelectedRtf = #"{\rtf1\ansi\v " + hideText + #"\v0}";
}
}

"yes it is static value"
This seems a trivial answer...
RichTextBox1.Text = RichTextBox1.Text.Replace("test2", "")
*Assuming the static value isn't part of another string.

Related

Selected Text Formatting in WPF RichTexBox

I am trying to implement programmatically selected (using regex) text formatting in a WPF RichTextBox. The use case is simply a WPF RichTextBox in which the user types text. However, to improve or accelerate readability i want to incorporate some automatic formatting as the text is typed.
The following code from How to select text from the RichTextBox and then color it? is exactly what i am trying to do. However, as far as i can tell this code is for a WinForms RichTextBox:
public void ColourRrbText(RichTextBox rtb)
{
Regex regExp = new Regex(#"\b(For|Next|If|Then)\b");
foreach (Match match in regExp.Matches(rtb.Text))
{
rtb.Select(match.Index, match.Length);
rtb.SelectionColor = Color.Blue;
}
}
I have tried to convert it as follows:
public static void ColorSpecificText(RichTextBox rtb)
{
TextRange textRange = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd);
Regex regex = new Regex(#"\b(For|Next|If|Then)\b");
foreach (Match match in regex.Matches(textRange.Text))
{
textRange.Select(match.Index, match.Length); // <--- DOESN'T WORK
textRange.SelectionColor = Color.Blue; // <--- DOESN'T WORK
}
}
However, i am stuck on how to convert the "match.Index, match.Length" and the "SelectionColor" syntax to something that the WPF RichTextBox knows how to handle. I have searched other posts, but most also seem to be for WinForms RichTextBox, not WPF. Any guidance would be greatly appreciated.
This is the syntax:
TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);
textRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Black);
Regex regex = new Regex(#"\b(For|Next|If|Then)\b");
int i = 0;
foreach (Match match in regex.Matches(textRange.Text))
{
var wordStartOffset = textRange.Start.GetPositionAtOffset(i + match.Index);
var wordEndOffset = textRange.Start.GetPositionAtOffset(i + match.Index + match.Length);
var wordRange = new TextRange(wordStartOffset, wordEndOffset);
wordRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.LightBlue);
i += 4; // could be something else
}
Although it may not highlight correctly because of your strategy. I'm afraid string index is not enough to create the proper TextPointer. +4 is used to skip formatting overheads, that's why it may not work if other formattings are present.

telerik listcontrol only shows part of item image

I am filling a listcontrol (Telerik for WinForms) by using the following code :
public static List<RadListDataItem> GetItems()
{
List<RadListDataItem> items = new List<RadListDataItem>();
for (int i = 1; i <= 10; i++)
{
RadListDataItem toadd = new RadListDataItem();
toadd.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
toadd.Text = "sssssssssss";
//toadd.Image.
string imagename = "MyProject.SuIcons.d" + i + ".JPG";
toadd.Image = new Bitmap(Assembly.GetExecutingAssembly().
GetManifestResourceStream(imagename));
items.Add(toadd);
}
return items;
}
but, only top portition of every item image is show in listcontrol, I mean I cant see the whole image associated with item in the list.
Would you help me please ?
You should set the AutoSizeItems property of the control to true in order to allow the visual items size themselves according to their content:
radListControl1.AutoSizeItems = true;
You can adjust the item size of the radListView. There is a property ItemSize that you can change in the designer view. Or if you want to do it programmatically, you can do something like this.
radListView1.ItemSize = new System.Drawing.Size(200, 400);
The first parameter is the width and the second is the height.

How to use the Insert Key (like in traditional windows) for a WPF 4 App?

Ok, I know that the new versions of windows do not use the insert key by default and you have to program for it. I want to be able to type in my text box and override the content that is in it just like in old windows when you could activate the insert key. This is just for my WPF 4, VB.net Application.
Updated Information:
That what I meant: I need to mimic old terminals. I need to activate the overwrite mode programmatically for all the controls. The same affect as the 'Insert' key on the keyboard. Only that key does not work in a WPF environment.
Example I am entering the word world over a text box that says 'Hello!':
Textbox Started as: [Hello!]
The Textbox is now [World!]
You will note that the one character exclamation mark stayed because world is not enough characters to replace the '!'.
Try this out (use this control instead of vanilla TextBoxes):
public class InsertModeTextBox : TextBox
{
public InsertModeTextBox()
{
InitializeComponent();
}
protected override void OnTextInput(TextCompositionEventArgs e)
{
var txt = e.Text;
var len = txt.Length;
var pos = CaretIndex;
var builder = new StringBuilder();
if (pos > 0) builder.Append(Text.Substring(0, pos)); // text before caret
builder.Append(txt); // new text
if (Text.Length > pos + len) builder.Append(Text.Substring(pos + len)); // text after overwrite
Text = builder.ToString();
CaretIndex = pos + len;
e.Handled = true;
}
}
In WPF 4 pressing Insert key when textbox has focus activates overwrite mode. Do you mean changing between Insert and Overwrite modes for all textboxes on a window at once?

Insert text into WPF textbox at caret position

How can I insert text into a WPF textbox at caret position? What am I missing? In Win32 you could use CEdit::ReplaceSel().
It should work as if the Paste() command was invoked. But I want to avoid using the clipboard.
To simply insert text at the caret position:
textBox.Text = textBox.Text.Insert(textBox.CaretIndex, "<new text>");
To replace the selected text with new text:
textBox.SelectedText = "<new text>";
To scroll the textbox to the caret position:
int lineIndex = textBox.GetLineIndexFromCharacterIndex(textBox.CaretIndex);
textBox.ScrollToLine(lineIndex);
If you want to move the caret after the inserted text the following code is useful
textBox.SelectedText = "New Text";
textBox.CaretIndex += textBox.SelectedText.Length;
textBox.SelectionLength = 0;
I found an even more simple solution by myself:
textBox.SelectedText = "New Text";
textBox.SelectionLength = 0;
Then scroll to the position as stated by Tarsier.
Use TextBox.CaretIndex to modify the text bound to the TextBox.Text property.
Late to the party, but I wrote this extension method, that inserts the text the same way as if you use the paste.
This handles MaxLength, CaretIndex and even Selection of text.
/// <summary>
/// Inserts text into this TextBox. Respects MaxLength, Selection and CaretIndex settings.
/// </summary>
public static void InsertText(this TextBox textBox, string value)
{
// maxLength of insertedValue
var valueLength = textBox.MaxLength > 0 ? (textBox.MaxLength - textBox.Text.Length + textBox.SelectionLength) : value.Length;
if (valueLength <= 0)
{
// the value length is 0 - no need to insert anything
return;
}
// save the caretIndex and create trimmed text
var index = textBox.CaretIndex;
var trimmedValue = value.Length > valueLength ? value.Substring(0, valueLength) : value;
// if some text is selected, replace this text
if (textBox.SelectionLength > 0)
{
index = textBox.SelectionStart;
textBox.SelectedText = trimmedValue;
}
// insert the text to caret index position
else
{
var text = textBox.Text.Substring(0, index) + trimmedValue + textBox.Text.Substring(index);
textBox.Text = text;
}
// move caret to the end of inserted text
textBox.CaretIndex = index + valueLength;
}

WPF FlowDocument: force calculation of height etc. "off screen"

My target: a DocumentPaginator which takes a FlowDocument with a table, which splits the table to fit the pagesize and repeat the header/footer (special tagged TableRowGroups) on every page.
For splitting the table I have to know the heights of its rows.
While building the FlowDocument-table by code, the height/width of the TableRows are 0 (of course). If I assign this document to a FlowDocumentScrollViewer (PageSize is set), the heights etc. are calculated. Is this possible without using an UI-bound object? Instantiating a FlowDocumentScrollViewer which is not bound to a window doesn't force the pagination/calculation of the heights.
This is how I determine the height of a TableRow (which works perfectly for documents shown by a FlowDocumentScrollViewer):
FlowDocument doc = BuildNewDocument();
// what is the scrollviewer doing with the FlowDocument?
FlowDocumentScrollViewer dv = new FlowDocumentScrollViewer();
dv.Document = doc;
dv.Arrange(new Rect(0, 0, 0, 0));
TableRowGroup dataRows = null;
foreach (Block b in doc.Blocks)
{
if (b is Table)
{
Table t = b as Table;
foreach (TableRowGroup g in t.RowGroups)
{
if ((g.Tag is String) && ((String)g.Tag == "dataRows"))
{
dataRows = g;
break;
}
}
}
if (dataRows != null)
break;
}
if (dataRows != null)
{
foreach (TableRow r in dataRows.Rows)
{
double maxCellHeight = 0.0;
foreach (TableCell c in r.Cells)
{
Rect start = c.ElementStart.GetCharacterRect(LogicalDirection.Forward);
Rect end = c.ElementEnd.GetNextInsertionPosition(LogicalDirection.Backward).GetCharacterRect(LogicalDirection.Forward);
double cellHeight = end.Bottom - start.Top;
if (cellHeight > maxCellHeight)
maxCellHeight = cellHeight;
}
System.Diagnostics.Trace.WriteLine("row " + dataRows.Rows.IndexOf(r) + " = " + maxCellHeight);
}
}
Edit:
I added the FlowDocumentScrollViewer to my example. The call of "Arrange" forces the FlowDocument to calculate its heights etc. I would like to know, what the FlowDocumentScrollViewer is doing with the FlowDocument, so I can do it without the UIElement. Is it possible?
My guess would be no, you can't do it without a UIElement.
FlowDocument, by itself, doesn't actually render anything. Looking at the type in relector it looks like it is just a data type. Its about like having a string and wanting to know its size when rendered ... can't really do it without doing some kind of measure pass.
I don't know for sure, but you might get better performance in the arrange pass by passing in Double.PositiveInfinity for the size rather than 0. At least then it won't have to worry about measuring 'n' line breaks.

Resources