I have a RichTextBox onto which I write long lists of data using a simple write method (see down)
I use vertical scrolbar, and writing and clearing is fine.
The problem is with new text after clearing the text.
I use textbox.clear(); which clears the box OK, but when new text arrives, the old (cleared!) text shows up again, followed by the new text.
I have also tried:
ResetText, Refresh, Update. dispose, Text =" , richTextBox.Document.Blocks.Clear(); (dont have that one).
Have also tried new textbox = new textbox, all for no avail.
The text shows again and again, until I reset the application.
I have seen several form threads on that one, but non helped.
My guess: I use both scroll bars. A scrollbar must have a buffer, The data is kept somewhere in the active scrollbar buffer?
Any (good) idea will be blessed.
This is how I write / erase the text in the richtextbox:
(simplified. mainDisplay is a RichTextBox)
public void mainDisplayText(string text)
{
this.mainDisplay.AppendText(text);
this.mainDisplay.ScrollToCaret();
}
private void btnClear_Click(object sender, EventArgs e)
{
//Have tried all these options:
this.mainDisplay.Text = ""; //or
this.mainDisplay.Clear(); //or
this.mainDisplay.SelectAll(); //or
this.mainDisplay.SelectedText = "";
}
You're reusing the same string, so:
this.mainDisplay.Clear();
text = string.Empty;
Should do the trick :)
Strange indeed. Could this be some issue in .net 4.7.x ? Since last week I compile everything in 4.7.2 and this problem has surfaced here also. Clear() seems to bring back the .Text content. So a Clear() after Text="" does not work.
Related
I've spent hours trying to understand what is happening here.
I have a RichEditBox that the user can interact with by tapping on it and using the keyboard or by tapping on a couple of buttons that add some characters inside the RichEditBox.
This is a method I use:
private void ptrPlus_click(object sender, RoutedEventArgs e)
{
try
{
myRichEditBox.Document.Selection.Text = ">";
myRichEditBox.Document.Selection.SetRange(this.Document.Selection.StartPosition + 1, this.Document.Selection.StartPosition + 1);
}
catch
{
//
}
}
What works:
• If I use only the keyboard to write inside the RichEditBox, it works fine
• If I use only the buttons, like this one, it works fine and the characters gets added inside the RichEditBox
What doesn't work:
• If I tap inside the RichEditBox (to either write inside or, or just to make the keyboard appear, and then tap outside it to close it), and then use the button again to add some characters, it works fine for the first two times I press the button.
On the third one, I get a System.AccessViolationException and my app crashes at the
myRichEditBox.Document.Selection.Text = ">";
The app crashes even if that line is inside a try/catch, I don't know why.
I tried to check the state of both the Selection index position and the Selection lenght before and after the RichEditBox got focus as I tapped on it, and it doesn't seem that they change in any way. So I don't really know what is happening here :/
Thanks in advance for your help!
Sergio
EDIT:
I added this handler for the LostFocus event:
void MyRichEditBox_LostFocus(object sender, RoutedEventArgs e)
{
String temp;
int start = this.Document.Selection.StartPosition, end = this.Document.Selection.EndPosition;
this.Document.GetText(TextGetOptions.FormatRtf, out temp);
this.Document.SetText(TextSetOptions.FormatRtf, temp);
this.Document.Selection.SetRange(start, end);
}
This should be rather pointless, but I discovered that it "fixes the error" (even though this shouldn't do anything). The downside is that it adds a new line at the end of the Document, I suspect that's because of the extra \r that the RichEditBox adds by default.
Any ideas on why this handler doesn't let the app crash anymore and/or how to get rid of the extra final \r? Thanks!
EDIT2:
I stopped the debug inside that method and I discovered that the Rtf String didn't contain \r at the end of it, but it had a series of \par that made the RichEditBox add a new line each time.
I tried:
temp = temp.Replace(#"\par", "");
Before the SetSext method, but this just messed up the content of the document, even though it did stop the RichEditBox to add new lines.
I'll if I can find a way to remove those \par without ruining the Rtf content.
If I copy some text with different format and paste it to my richtextbox it is not plain I mean its format will be copied as well.
Is there anyway I can copy-paste as a plain text?
By the way my program is on WinForm
thanks for any answer
you must use WinForm RichTextBox (not in UI, just in code), even if you are on WPF, in order to convert RTF to plain text. Use this method in your Copy event.
C# code :
private String ConvertRtfToText()
{
System.Windows.Forms.RichTextBox rtfBox = new System.Windows.Forms.RichTextBox();
rtfBox.Rtf = this.rtfData;
return rtfBox.Text;
}
VB.Net Code :
Private Function ConvertRtfToText() As String
Dim rtfBox As RichTextBox = New RichTextBox()
rtfBox.Rtf = Me.rtfData
Return rtfBox.Text
End Function
source : http://msdn.microsoft.com/en-US/en-en/library/vstudio/cc488002.aspx
I recently had the same issue. I did want to retain some of the formatting, i.e. paragraphs and line feeds, but I required all the addition text format to be removed.
I'm working in WPF but the RichTextBox interface is the same. I have created a button that will allow users to select some text and remove the formatting. It is very simple, you just need to use the ClearAllProperties() method on the TextSelection object.
C# Code (WPF):
private void ClearFormat_Click(object sender, RoutedEventArgs e)
{
rtbText.Selection.ClearAllProperties();
}
This is a super easy solution but perhaps not super elegant...
1) Add a plain textbox to your form and make it hidden
2) Create a button to remove the formatting (or you can do this
automatically when the text is pasted)
3) In the OnClick (or OnPaste) code just copy the text from the rich
textbox control to the plain textbox control then copy the text
from the plain textbox back to the rich textbox control (see example
below)
private void btnRemoveFormatting_Click(object sender, EventArgs e)
{
txtPlainText.Text = txtRTF.Text;
txtRTF.Text = ""; // Required - this makes sure all formatting is gone
txtRTF.Text = txtPlainText.Text;
}
So I'm using this code which moves the cursor to the end of the text box content each time I'm adding something to it.
void txtDisplay_TextChanged(object sender, EventArgs e)
{
txtDisplay.SelectionStart = txtDisplay.Text.Length;
txtDisplay.ScrollToCaret();
txtDisplay.Refresh();
}
The problem is that I see like flickering of text box scroll bar which goes up and down each time I add something to the text box. Doing this 10 times a second seems like it consumes some processing power and it looks ugly.
How to keep the scroll bar scrolled down all the time?
Hi there ( again :) ),
I've just looked for some methods to avoid this flickering and I found this post exploring both SelectedText property and AppendText() method, with the lattest actually appending the text and scrolling only if it's necessary.
Hope that'll help !
How would you prevent the user from adding or removing lines in a TextBox? By that I mean, if I set the text in a textbox to 7 lines with some text, how can I make sure that it will always be 7 lines of text there? The user must be able to edit those lines like usual, but not remove a line entirely, and not add any new ones.
Would have to take into account both keyboard input and also things like cut and paste, etc.
Any good ideas?
Reason: I want to make a file renamer kind of like Oscar's Renamer. You give it a folder, and it loads the filenames into a textbox where you can do changes pretty much like you do in a text editor. When you are happy with your changes, you write them back. Reason for constant n lines in textbox is then of course that line n is the name of file n. Adding a new line shouldn't be allowed since you only have those files in that folder. Removing a line should also not be allowed since you would then be missing a name for a file.
Why go through the trouble of making something like this when it already exists? Well, I am curious to see if I could do it, and thought it could be a nice excercise to learn a few things along the way. Since it has some interesting problems that needs to be solved. Like this one :) There are also some features I think are lacking in that Oscar's Renamer. So... to sum up: I'm doing it to learn and to try make an even better version of it. I know fully well that I may just as well fail completely though, or just never finish it :p But that is another story. I want to learn
You have the wrong interface then for the data. In this case, you should have a fixed number of textboxes, one for each line of data. This would allow the user to modify the contents of each line, but not remove a line or add a line.
Trying to make a multi-line textbox do this will be maddening at best, since you will have to determine when a new line is added/removed and then kill the change.
Why not use a Listbox instead?
I'd probably let the user do what they want on the textbox, then add validation to show the user there is an error when they go above 7 lines (e.g. red-outline and tooltip or something). If they are under 7 lines, no problem, add them when you come to process that data.
What is the specific reason you want the always 7 lines? Like casperOne said, maybe the interface you're using isn't ideal to your needs.
One possible way of doing this is to sub-class the Textbox control and override the winProc method. This method handles all window messages pumped to the windowed control (Textbox in your case). You could monitor the use of the backspace and delete keys and carat position and discard the key strokes that attempt to remove carriage return line feed sequences. And provide the user with an interactive alert that tells them why they cannot remove entire lines.
Doing it this way gives you complete control and is the lowest level way to see all input that is coming into your Textbox control. You can intercept certain messages and discard them, the ones that you want to allow just pass them through into the base class method. Such as if the user highlights all lines and hits the delete key. There is other event handlers that you can use to intercept keyboard input but they have some limitations, the winProc will allow you to check any message directed to the control including delete, backspace copy and paste etc, mouse clicks etc.
Sample:
public class myCustomTextBox : TextBox
{
protected override void WndProc(ref Message m)
{
if (m.Msg == 770) // window paste message id
{
string clipBoardData = Clipboard.GetDataObject().GetData(DataFormats.Text).ToString();
handlePasteEvent(clipBoardData);
}
else
{
base.WndProc(ref m);
}
}
private void handlePasteEvent(string pasteData)
{
// process pasted data
}
}
Since you already have stated that this is a learning project, a see if I can do it-project, I think you should throw in some WPF into it. A listbox with a itemtemplate would solve this very nicely.
If that's out of the way, I would consider using a datagrid instead of a textbox.
Load your data in a editable DataGrid instead of a TextBox, that should make things much more simple, and also you can pick which columns are editable and which are not.
Here's an example that uses a DataGridView and simulates your textbox:
The grid lines are hidden.
The headers of columns and rows are hidden.
The background color is the same color a TexBox has.
Add a DataGridView to a form and use the following code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.dataGridView1.AllowUserToResizeRows = false;
this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
this.dataGridView1.BackgroundColor = SystemColors.Window;
this.dataGridView1.BorderStyle = BorderStyle.None;
this.dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;
this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.ColumnHeadersVisible = false;
this.dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;
this.dataGridView1.MultiSelect = false;
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.SelectionChanged += new System.EventHandler(this.dataGridView1_SelectionChanged);
dataGridView1.DataSource = Directory.GetFiles(Environment.CurrentDirectory).Select(f => new FileEdit { FileName = Path.GetFileName(f) }).ToList();
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
dataGridView1.BeginEdit(true);
}
}
class FileEdit
{
public string FileName { get; set; }
}
}
I have a Windows Forms C# application where I would like to use a tooltip on one of the text boxes. I initialize the tool-tip in the constructor of the Form class, and it works the first time. So when I hover over the text box with my mouse it works, but once the toolTip times out and it goes away, it does not re-appear when I move my mouse away and back onto the control. I would expect it to come back. What am I doing wrong?
Here is how I initialize the tooltip:
myTip = new ToolTip();
myTip.ToolTipIcon = ToolTipIcon.Info;
myTip.IsBalloon = true;
myTip.ShowAlways = true;
myTip.SetToolTip(txtMyTextBox,"My Tooltip Text");
I had a similar problem today. Sometimes, the tooltip would not show. I had one ToolTip control for all the controls in my form.
I also had a MouseEnter event on all the controls added automatically, so I modified the MouseEnter event to do:
_tooltip.Active = false;
_tooltip.Active = true;
It fixed the bug, but I don't know why.
Also, the bug always happened on Windows XP machines, but not on Windows Vista.
I guess you'll be happy to know that Microsoft knows about it...since about 5 years...
2/21/2005 Bug acknowledged as reproducable
3/29/2005 Hum we might fix it, but later...
11/15/2005 Well actually it's not a big bug, and it doesn't happen much, so we won't fix it.
Damn I love it when I stumble on bugs Microsoft doesn't want to solve! This time it's called a corner case, last time it was simply too difficult to resolve...
http://connect.microsoft.com/VisualStudio/feedback/details/115385/tooltip-stop-showing-after-autopopdelay
I'm off to tell my client that the bugs in my program are just corner cases and too difficult to resolve...
I had a similar problem today. VS 2010 SP1 .Net 3.5
After AutoPopDelay-Time the ToolTip do not show the Controls ToolTipText.
Kevins solution is the only way to solve the problem.
I encapsulate this in my own ToolTip class:
public class ToolTip : System.Windows.Forms.ToolTip
{
public ToolTip() : base() { }
public ToolTip(System.ComponentModel.IContainer components) : base(components) { }
public new void SetToolTip(System.Windows.Forms.Control ctl, string caption)
{
ctl.MouseEnter -= new System.EventHandler(toolTip_MouseEnter);
base.SetToolTip(ctl, caption);
if(caption != string.Empty)
ctl.MouseEnter += new System.EventHandler(toolTip_MouseEnter);
}
private void toolTip_MouseEnter(object sender, EventArgs e)
{
this.Active = false;
this.Active = true;
}
}
I had this issue in VB.NET. What I did was drop a TooTip control on the form, and then on the target control's MouseHover event, I set the properties of the ToolTip. I did this because I used one ToolTip control for five different Label controls. It worked great. (Really, I wanted the ToolTip to show immediately, so I used the MouseEnter event instead.) I can post my exact code tomorrow when I get to work.
I solved this problem by this
if (t == null)
{
t = new ToolTip();
}
t.IsBalloon = true;
t.ToolTipTitle = "Stop";
t.ToolTipIcon = ToolTipIcon.Error;
t.Show("", yourControlonWhichToApplyToolTip, 0);
t.Show("PDescription", yourControlonWhichToApplyToolTip, 1000);
Note i have added an empty tooltip.
For what it's worth, I was having this problem on my Windows XP system until I noticed that if I placed at least one tooltip control on my form manually (from the toolbox) I could create as many tooltips as needed within my code, and they would all work.
If, however, I tried to create all tooltips in code (say for instance in the formload event) the tips would only show once and never to be seen again. I can't give you the exact "why this happens" story, but I have duplicated this issue several times always with the same effect. It might have something to do with the object scope, but I'm not sure.
So now just as a habit, I always include at least one Visual Studio tooltip control and then the rest within my code.
I just had the the problem on Windows 7 so I found this thread.
In my case this did not work in tooltip_MouseEnter:
tooltip.Active = false;
tooltip.Active = true;
So I tried the following:
this.toolTip.SetToolTip(this.txtbx1, "tooltip-text");
This worked fine for me.
In my case after setting the tooltip text with the SetToolTip method, I used the Show overload with duration parameter, i.e.
toolTip.Show(text, textEdit, 1000);
After that tooltip did not reappear on mouse hover, and resetting tooltip.Active didn't work..
A workaround that worked for me was to use Show overload without the duration, and hide it manually afterwards:
toolTip.Show(text, textEdit);
new Task(() =>
{
Thread.Sleep(750);
textEdit.Invoke(new Action(() => toolTip.Hide(textEdit)));
}).Start();
With this code I have the desired behaviour, i.e.
The tooltip is shown at once for 750 millisec. after the tooltip text has changed
The tooltip does appear for the specified time when the mouse is over the control
System.Windows.Forms.ToolTip ToolTip1 = new System.Windows.Forms.ToolTip();
private void textBox_MouseHover(object sender, EventArgs e)
{
ToolTip1.Show("YOUR TEXT", textBox);
}
private void textBox_MouseLeave(object sender, EventArgs e)
{
ToolTip1.Active = false;
ToolTip1.Active = true;
}