textbox properties - c#

I have set the MaxLength property of a textbox in my windows forms application to 10
I am populating the textbox by reading from a file. However if a read string which is more than 10 characters the textbox still gets populated. But when I manually try to enter a string it works fine (that is, it does not allow more than 10 characters to be entered).
Why is there a difference between these two behaviors? How can I populate my textbox from the file and still have the MaxLength property to be working?
Thanks,
Viren

From the TextBoxBase.MaxLengthProperty specs:
In code, you can set the value of the Text property to a value that has a length greater than the value specified by the MaxLength property. This property only affects text entered into the control at run time.
In other words, you must limit the amount of text in code when pulling from a data source.
For Example:
string text = "The quick blue smurf jumped over the brown fox.";
textBox1.Text = text.Substring( 0, textBox1.MaxLength );

It's never wise to rely entirely on instant validation of values - you should always validate the final value as well. For example, i've seen people regularly using KeyUp/KeyDown/KeyPress events to disallow various characters, and then forgetting that people regularly use copy-and-paste (which negates the intended validation).

You'll have to limit it programatically. That's simply the way the browsers treat HTML. Sorry :(
Unfortunately, the HTML spec doesn't offer any guidance on this issue (that I can find) so the browser makers have settled on this behavior.
http://www.w3.org/TR/html401/interact/forms.html#h-17.4

At the very worst, you could try to limit your data to 10 characters when you are binding to the textbox:
txtMyTextbox.Text = Left(myData, 10)

Related

What is the most general way to format textbox text value with both static and dynamic elements?

I'm currently working on a form with a bunch of textboxes with quite specific requirements. For example one textbox contain cadastral number and should look like ##:##:#######:~ (last range of digits varies) and also it would be quite nice to see the pattern before you even type anything (if I recall correctly it's called mask). Also giving requirements first two digits always should be 24, so the end result should look shomething like this 24:##:#######:~. Another example is a numeric textbox with units and spaces between big digit numbers (ex 1 000 000 m2). For short this one text box and the others have both static elements (which user should not be able to edit) and dynamic (which makes masked textboxes and similar stuff quite hard to deal with).
So, I've tried different things:
Using maskedTextBox from toolkit package, which turned out bad, because it did poorly handle last part with range of digits, and also when a key was pressed when in the middle of the static mask, it just pushed the carret, but not actually add anything to the text;
Using converters prove quite chalenging at first, but gave remarcable results, it handles variable range of part perfectly, partialy, because of custom converter, but it was difficult to manage things, when user deleted text, because of static parts being integrated in the converter itself;
Using StingFormat for textbox with binding text property was almost useless, although it handle static part quite well, and in the end I couldn't make it work.
Intuition tells me a combination of a custom converter (handling dynamic part) and and StringFormat (handling uneditable static part) should do the job. Maybe the number of requirements is just too much for a simple textbox. Also one thing is bugging me, there could be a sutable existing general solution, that I am not aware of (At first I didn't know Converters was a thing).
Now the question, how would you generally approach this problem? Is there any existing solutions, that with a bit of tweaking would work?

RDLC text overflow behavior

I'm working on converting an older reporting format into RDLC and am running into a problem. In a few edge cases a numeric value overruns its allotted display space -- it's, let's say, '10000%', and I can't just set "CanGrow" to false and let the field truncate since the percent sign must be visible.
In the original reporting format a field too big for its allotted display space just displayed as a bunch of asterisks, so I've got a question in two parts:
1) Is there a way to format the data in RDLC so it displays an alternate string if it runs over a certain value?
2) Is there a way to apply that format for printing only, so that on exporting the data to, say, Excel (with Report.Render) the field will still say '10000%'?
For posterity, what worked here was combining the Globals!RenderFormat field with filtering based on the value. For example
IIF(Globals!RenderFormat.Name Like "excel*" Or
(Fields!Percent1.Value > -10 And Fields!Percent1.Value < 100),
Fields!Percent1.Value, "******")

Formatting text with padding does not line up in C#

I am fairly new to programming and I just wrote a simple application in C# .NET to retrieve information about system drive space. The program functions fine but I'm struggling with formatting the output.
See output:
I'm trying to use padding to get the text to line up in sort of a column format within a rich text box but the output doesn't line up because if there are multiple drives, the drive names are different lengths which throws off the padding. Even if the drive letter comes back one as M: and the other as I: the difference in the size of the letter is enough to throw off the alignment while padding.
I am wondering if there is a way to force each string value to a specific length so the padding is applied evenly or if maybe there's an even better way to format my output. Thank you in advance for your time and let me know if any further information would be helpful!
Note: One of the comments asked an important question, regarding whether the question refers to the System.Windows.Forms.RichTextBox (WinForms) or the System.Windows.Controls.RichTextBox (WPF) control. This answer applies only to the WinForms version of RichTextBox, so if you're using WPF, this doesn't apply.
The most important thing, and this was mentioned in the comments, is that you'll need to use a Monospaced font.
Since you stated you're using a RichTextBox, you'll need to know how to set it to use whatever monospaced font you've chosen.
To do that, you can use the RichTextBox.SelectionFont property.
For more general instructions, refer to this MSDN article: Setting Font Attributes for the Windows Forms RichTextBox Control
Once you set the RichTextBox.SelectionFont property, only text added to the control afterwards will use the specified font. To apply the font to existing text (i.e. you populate the RichTextBox and then change the font to an appropriate monospaced font), take a look at this answer, which tells you precisely what to do.
Once that's done, there remains the simple matter of adding the appropriate amount of whitespace to the end of each string, such that the next piece of data appears at the appropriate position. You'll probably be using String.PadRight, but for more general information about padding strings, check out this MSDN article: Padding Strings in the .NET Framework
Here is string formatting example:
string varOne = "Line One";
double varTwo = 15/100;
string output= String.Format("{0,-10} {1,5:P1}", varOne, varTwo);
//expected output is
//Line One 15 %
where formatting properties in curly brackets are:
{index[,alignment][ :formatString] }

Change DataGridViewCell user input handling behavior

I have a winform app with a TimeSpan column that displays the hours/minutes part of a date. When the user enters text it is converted to a TimeSpan using TimeSpan.TryParse(). This works as expected when the user input is "11:00" in setting a value of 11 hours. The problem is that if the use enters "1100" it is parsed as 1100 days which is not what I want, nor is simply saying "bad input" in the `CellValidating event satisfactory behavior.
The users input is provided in the readonly property DataGridViewCellValidatingEventArgs.FormattedValue so I can't change the value being passed through the call chain. DataGridViewTextBoxCell.EditedFormattedValue is also read only and I can't find any other event or property that lets override the default behavior.
This is very frustrating. I can write a many stepped fall through validater that can handle multiple user input formats and get the intended value from each; but unless I throw away all the strongly typed data binding that the framework offers and instead create a shim object that stores all values as strings there doesn't seem to be any way to do so.
Somehow among the 10 billion events in the DataGridView I managed to overlook CellParsing. Overriding it lets me do what I need to do.

Writing huge amounts of text to a textbox

I am writing a log of lots and lots of formatted text to a textbox in a .net windows form app.
It is slow once the data gets over a few megs. Since I am appending the string has to be reallocated every time right? I only need to set the value to the text box once, but in my code I am doing line+=data tens of thousands of times.
Is there a faster way to do this? Maybe a different control? Is there a linked list string type I can use?
StringBuilder will not help if the text box is added to incrementally, like log output for example.
But, if the above is true and if your updates are frequent enough it may behoove you to cache some number of updates and then append them in one step (rather than appending constantly). That would save you many string reallocations... and then StringBuilder would be helpful.
Notes:
Create a class-scoped StringBuilder member (_sb)
Start a timer (or use a counter)
Append text updates to _sb
When timer ticks or certain counter reached reset and append to
text box
restart process from #1
No one has mentioned virtualization yet, which is really the only way to provide predictable performance for massive volumes of data. Even using a StringBuilder and converting it to a string every half a second will be very slow once the log gets large enough.
With data virtualization, you would only hold the necessary data in memory (i.e. what the user can see, and perhaps a little more on either side) whilst the rest would be stored on disk. Old data would "roll out" of memory as new data comes in to replace it.
In order to make the TextBox appear as though it has a lot of data in it, you would tell it that it does. As the user scrolls around, you would replace the data in the buffer with the relevant data from the underlying source (using random file access). So your UI would be monitoring a file, not listening for logging events.
Of course, this is all a lot more work than simply using a StringBuilder, but I thought it worth mentioning just in case.
Build your String together with a StringBuilder, then convert it to a String using toString(), and assign this to the textbox.
I have found that setting the textbox's WordWrap property to false greatly improves performance, as long as you're ok with having to scroll to the right to see all of your text. In my case, I wanted to paste a 20-50 MB file into a MultiLine textbox to do some processing on it. That took several minutes with WordWrap on, and just several seconds with WordWrap off.

Categories

Resources