TextBox Text Management - c#

I have a WPF application where I'm trying to create a "diagnostics panel" that's very similar to the "Output Window" in Visual Studio 2010. It simply contains a text box where all types of output are collected and appended in the text box using the .AppendText() method.
We have a couple of customers who leave this diagnostics panel up all the time and never clear it. As a result, a very large amount of text gets displayed as new output continues to come in...
The WPF TextBox has a MaxLength property which I leave set to 0. According to the MSDN documentation, "When this property is set to 0, the maximum length of the text that can be entered in the control is limited only by available memory."
For the customers that leave this panel up, I hate to just let the text and memory grow uncontrolled... I think this may eventually cause the application to hang up...
I am curious if there's a good way to mange this... I want to keep a certain number of lines displayed in the text box and discard the oldest as new lines come in...
Any thoughts?
Thanks!

Why not use a listbox with each sentence getting its own textblock - so you can get virtualization?
http://social.msdn.microsoft.com/Forums/en/wpf/thread/98090161-0abf-4799-bbcb-852dcc0f0608

You could have a DispatcherTimer in your code behind. With this you, you can set it to Tick every 10 minutes (or whatever time period you want). And in the Tick event handler method, you can take the text in your textbox, throw away the all but the amount of text you want to save and then set the that text back to the textbox.
You could also save the text to a log text file. You'd have to figure out what to append to the text file so you won't write the same text to it multiple times. This depends on what exactly your needs are.
DispatcherTimer documenation
Like Xaisoft said, you shouldn't use a TextBox for this, probably a TextBlock instead. You might have to put that inside a ScrollViewer, I don't remember.

Here's how you handle it:
Write the log info to a text file
Write the log info to your text box (although I don't like textboxes, it should be okay.)
When writing to the text box, only display the last maybe 20 or so (play with this) lines. Everything else should "roll off"
If your users really want to save everything, no biggie, it already is saved to that file.
Upon each execution of the app, or at some appropriate interval, roll your logging to a new file.

Related

C# textbox endline

What I'm trying to do is insert, from a text box, into a MS Access database some text (no surprises). Thing is that after submitting what I have written, when I open the Access database it all appears as one string of text. So my question: is there a way in which I can determine the end of the text box per line so that when it reaches that point it would make a new line? Or something similar so that it would introduce a new line into the database file because this issue is very annoying.
P.S.: Yes the multiline option is enabled.
Thank you very much.
I believe you are trying to solve a non-problem. Quite possibly you'll find that you will want to show the same text in a number of different places within your application or even different applications (if it's not true now it MIGHT be true at some point in the future), so it should the the GUI to decide where and when break a text line, not your DB
You could either detect Environment.NewLine within the textbox's text, or you could use the Lines property to access each line individually.

How to force a textbox to update its text

So I've looked through maybe five to ten questions on stackoverflow about setting text into a textbox using a range of commands. I've tried SetWindowText, SendMessage with EM_SETSEL and EM_REPLACESEL, and a few others that I can't think of off the top of my head. For the most part I have been successful, except for one strange occurrence.
When I set the text of this specific text box, nothing appears, nothing changes. At first I thought I was not setting the data correctly. However, when I use Spy++ or Winspector to see the text of a textbox, the correct data with my changes are in there, but not displayed on the actual textbox. Even stranger, when I click back into the form with the textbox I "edited", spy++ and Winspector's data changes to what the textbox is displaying.
I spoke with a friend of mine and he mentioned it might be a race condition. I'm trying to edit this box and the textbox is being edited by some other thread as well.
If anyone has any suggestions I would really appreciate it.
Edit: Alright so I did some more digging into what is causing the problem with the text changing back. I opened up Winspector and had it watch the textbox. From there I was able to identify the messages sent to the window between the final time the text data is correct, to the first time it changes. I also exported the results to an xml document with the parameters, but it is about 680 lines long.
Heres the list of messages:
http://i.imgur.com/SBCFHK8.png
The control may just need to re-paint itself.
You can try two API's to do that:
InvalidateRect - PInvoke
RedrawWindow - PInvoke

Always ensuring text editor ends with X text

I am currently implementing a form that allows the user to input a lengthy message. For this application, the user's text must have some preset text added to the end.
An example would be:
Hello, I'm a message. END
How would I add the 'END' text in a text editor and enforce it to always remain at the end of the text? I want to show it there at all times and disallow the user from deleting or editing it. Do you know if this is possible?
My initial thoughts would be to on the TextChanged event, check if the characters are already on the end, and if they are not, delete them. But simple logic like that just seems bound to cause problems, and I was wondering if there is a known method of doing something like this, as unusual as it may seem.
You can add a handler for the KeyPress event, and if the key represents an edit that you don't want applied set the value of KeyPressEventArgs.Handled to true before returning.
If you need predefined text at the end of text entered by user then add that text at the end of message in code behind. Use text which are very rare to be entered by the user. Like ##END##. So you knows ##END## is the end of the message. When showing that message back to editor substring message till the index of ##END## in your code and display only actual message to the user.

Displaying log file in a multiline textbox

I'm writing data to a log file and need to display that data in my WinForms UI. My initial thought was to use a multiline textbox like this:
private void UpdateUITextbox(string text)
{
textBoxStatus.AppendText(text + Environment.NewLine);
}
I don't write a huge amount of text to my log file but over time, it's going to add up and I'll probably end up exceeding whatever the default maxlength for a multiline textbox is. The only thing I can think of to do to prevent this from happening is to hook into the OnKeyPress event handler and check the length of the textbox before I add something to it and, when necessary, to remove the older text to make room for the newer text. But this seems like it would definitely have an impact on performance. Someone please tell me that there is a better way to do this?
A Winforms TextBox has a maximum length of 2GB.
You'll have to worry about usability long before you worry about memory issues - if the log is too long, your users are not going to be able to use it effectively.
We show our log using AvalonEdit. It scales very well up to hundreds of thousands of lines.
Instead of a multi-line text box why don't you use a list box ?
And for the log, its best to add more information to your logs while saving them such as the time.
And on the load read each line which has a date stamp in the range you think is fairly recent.
It is not wise to to load all of your log files just at once. load only the new ones.
If you need to see the older logs,You can still manage that using the time/date stamp solution.

How to add text to a textbox and treat it as a block of text?

I want a textbox that it is possible to add "text blocks" to it. The definition of a "text block" is:
Deleting a char in the textbox that is part of a block causing to the whole block to be deleted.
Setting the carot position in the textbox in a location that is part of a block causing to the whole block to be selected.
Any attempt of the user to write a char in a middle of a block will fails followed by an appropriate message box.
I have a DataGridView with a CellClick event attached to it. I want that when the CellClick event is occurs, the content of the cell will be placed in a textbox and will be considered as a text block. The location of the added block will be in the carot position of the textbox or at the end of the textbox if the textbox is not focused and thus the carot is not blinking.
I also want that the textbox could function as a normal textbox, meaning that the user can add or delete any chars/text he want excepts the text blocks that they must be added/deleted completely as defined above.
Maybe I need to use some other GUI controls except textbox to accomplish this mission, I don't know.
I thought about some solutions but I don't know which is the best (maybe none of them):
(remark: each of the following solutions assumes that there is an KeyPress event attached)
Adding hidden characters (if possible) before and after each block to mark it.
Creating a list of objects which represents all the text blocks, each object containing two fiels: startIndex, endIndex. Not so good because adding or deleting chars from the textbox requires to update all the indexes of the blocks located after the added/deleted chars by +1 or -1 for each char.
Creating a list of objects which represents all the text in the textbox, each object containing two fields: text, flag. Each time a char is added manually or a word is added by the event, an object is added to the list and the object's text field is set to the added chars, and the object's flag filed is set to true if the chars are a word added by the event, or false otherwise.
Splitting the textbox to 2 parts and creating a small textbox between them for each text block added by the event, and treating the small textbox diffetently. When the text in the small textbox is deleted the whole textbox control is deleted and the splited textbox is united. Doesn't sounds me so good.
What is the best way to implement this?
Thanks!
I have never seen a control with this behavior. I'm not saying that someone hasn't written one, just that it's unlikely. This means that you're going to have to build it.
If you've never created a custom control, search the web for "creating custom winforms controls" or similar. You first need to understand the basic techniques.
Then you're going to want to know how to store the underlying text for editing. You can start by learning some of the techniques commonly used for standard text-editing controls. Pick one that you can modify for your custom scenario. Here are a few off the top of my head:
Gap Buffer
Rope
Piece Chains
Good luck!

Categories