I'm creating a flat file reader (simple hex editor if you will) in c# using RichTextBoxes. One RTB shows the hex values and another shows the ASCII values.
My plan is to show one 'record' per line. So, if there are 10 records I want to look at with a length of 1000, there will be 10 lines of 1000 characters per row in the ASCII and the hex side will have a length of 3000.
I dynamically set the rtb.RightMargin property to the length of one record.
The problem I'm running into is when the records are incredibly long, over 3500 chars for the ascii side making the hex side very large, I find that the text starts to disappear in the middle and end of the records when the right margin becomes too large. So for example:
hexRtb.RightMargin = 7500 //This is because it's triple the size of the ascii text.
In the hex rtb, it'll show the first parts of the text until I start scrolling towards the middle where all text stops showing completely. If I manage to click on these empty parts of the record, text will show up, but then disappear again after scrolling away.
I cannot figure out what's going on. This only seems to happen when the RightMargin is set to an incredibly large number. Smaller numbers, all text will shows without a problem.
Anyone ever encountered something like this?
Here's a code sample if it helps.
int asciiRecordLength = mHexReader.RecordSize;
int hexRecordLength = mHexReader.RecordSize * HexByte; //This is to convert the ascii record length to a hex record length
asciiTextBox.RightMargin = TextRenderer.MeasureText(mHexReader.GetAsciiValues().Substring(0, asciiRecordLength), asciiTextBox.Font).Width;
hexTextBox.RightMargin = TextRenderer.MeasureText(mHexReader.GetHexValues().Substring(0, hexRecordLength), hexTextBox.Font).Width;
//Populate text boxes
hexTextBox.Text += mHexReader.GetHexValues(); //This gets all of the records to be read
asciiTextBox.Text += mHexReader.GetAsciiValues();
For those who've run into the same problem I have, I found a workaround to this problem.
Instead of using RichTextBox, I found another control you can download called ScintillaNET. So far, I've been able to switch over most of my code to using this control without any problems. Some of the functions are slightly different, such as, instead of hextTextBox.Clear() it's hexTextBox.ResetText(), or hexTextBox.SelectionStart is now hexTextBox.Selection.Start.
Minor differences but this control fixes the issue with the pixels disappearing when the record length becomes very large.
The code can be downloaded from: http://scintillanet.codeplex.com/
Hope this helps anyone else who has run into the same problem I have.
Related
I've seen quite a few questions about scaling a TextBox to the size of the text, but only found a single question which talked about the reverse here. That question is also from 2010, and I believe the language has evolved since then, and there might be better solutions.
I'll clarify that I do not want to limit my input to an arbitrary number of characters, as the input may include newlines/vertical space. (Which, if it contained a lot of vertical space, could stretch the text beyond the bounds.)
Here's the situation:
Form 1 has a textbox. I want this textbox to remain a fixed size. Any data beyond the size should be cut off from the input.
I want to save Form 1's textbox's contents to a file.
In Form 2, I want to open the file and pull what was Form 1's textbox's contents. These will be saved in a separate textbox local to Form 2.
My strategy right now is to find a way to limit the input to the dimensions of the textbox, so that the textboxes in Form 1 and Form 2 are equivalent, and do not overflow their respective dimensions.
So my question is: How would I go about doing that?
Edit: Sorry, it appears my question didn't provide enough information. I also mis-typed the situation, so I'll re-write it below.
I'll step back and describe more of what I'm trying to do.
Let's assume I have a single Form, with the following two objects:
Textbox
Label
Anything I type into the Textbox I want to see on the Label's text. Input can be any letters, numbers, or special characters, including spaces and newline characters.
For the sake of consistent sizing, I want the label to be of a fixed graphical size; regardless of the number of characters in the label's text, the label object should be no larger than (x, y), where x and y are arbitrary height and width sizes.
I do not want data in the Textbox that cannot fit within the bounds of the label's size. The user should be prevented from entering data into the Textbox that would extend beyond the label's size bounds.
Are there any strategies not mentioned in the linked question that can determine whether a Textbox's text meets or extends past an arbitrary width and height?
The properties of the textbox give you a max length, you can also do it in code like so
var tb = new TextBox();
tb.MaxLength = 10
if you don't want to use that then you should use
var str = tb.Text.Remove(0, 10)
this will only give the str variable the first 10 characters no matter the length of whats actually in the textbox.
For what you want on form two, you need to give me more information about what you want.
edit after OP's edit
if you want the text in the textbox to be matched at the label level you want add a TextChanged Event to the property of the textbox and then have something like this
private void TextChanged(object sender, EventArgs e)
{
label1.Text = textBox1.Text;
}
having the label to a fixed size no matter what is isn't going to be good, ive done it, but this also begs the question, why are you duplicating your textbox information into a label. Why not just have it in a textbox
I've got a really simple setup - I have a string, a font and a font size on the ready. I want to render this to a Silverlight WriteableBitmap.
There's one catch - I want to be able to tell apart the letters in the rendered text. Ideally, I'd like to have a System.Windows.Rect for every rendered letter.
The problem is Silverlight's API, which is missing all of the useful stuff like Graphics.MeasureString, which I could have used to measure the letters separately.
What adequate options do I have to get the letters' measures in codebehind?
I sort of figured this out on my own. The solution is slow and far from perfect, but hey, it works!
The idea is to render the text many times, adding one letter at a time, and finding the difference between the current and previous TextBlock widths.
So, for example, if the text is "ab", we first render "a" and get its length. Then we render "ab" and find the difference, which should be the size of the rendered "b".
I need to overflow text of a cell that has too much data. I can't easily split it up into multiple cells so I guess the only choice now is to overflow it, but I just cant seem to find a way to do it.
wb.Cells(1, 1) = bigstring
wb.Cells(1, 1).WrapText = True
If your problem is that they aren't displaying in the cell it is because the amount of characters displayed is cut off after 1024 characters. The value is still stored and you can see up to 32k characters in the formula bar.
wb.Cells(1, 1) = bigstring.Substring(0, 3276)
stringHolder = bigstring.Substring(32767)
Will store any leftovers that are too big for your cell to hold. I'm not sure if this is what you mean by "overflow" but it should let you handle any data that is too big to fit in a cell.
Another solution might be to add the large string to a comment box on that cell, so users could see the whole thing when they click on it without having to look at the formula bar
I set up a draw rectangle to draw simple formatted text first aligned to the left as
*item 1
[1]Something
content
[2]Something else
<a> subsomething else
content
<b> another subsomething else
content
*item 2
The end.
and I would also like it to automatically create a new column (after checking for the longest string in the first column [drawn stuff on the left hand side]) to draw the rest into it.
In order to keep track of the paddings and itemized sections and subsections, I think of using a stack which I can push and pop the current and next positions needed to draw a text line each time I leave a content. Yet, I can't figure out how to jump back to a certain subsection position because stack doesn't offer an inline sub-scripting method.
Then I look into a hash-map (in C# I have tried Dictionary) to keep track of it and to access the value via specific key. For that I also use a external global variable to maintain the number of subsections the user may have entered and increase one each time a new subsection is created; and the float value is used to store the x-coordinate value for the drawstring to be done. This is complicated to me at least at present when I don't really have a nerve to go into it anymore. I can only receive false simulated outcomes.
So I am asking for an easier approach to tackle this problem, which I think is simple to many of you sure experiencing the same situation. I am desperately looking forward to seeing a short easy method to do this.
Draw formatted text using ..
..whatever works. I suggest a JLabel, which will render (simple) HTML/CSS formatted content.
See LabelRenderTest.java for an example.
So I'm building a custom control in C# (not WPF), and I basically want to implement text highlighting with the mouse.
How do I efficiently find the character at a given Point (say where the mouse is clicked) in a string? I have the layout rectangle of the string as it was drawn and I could calculate the length of the string up to every character until I find the one closest to where the mouse is clicked... but there has to be a better way. Any suggestions?
If I had to do this, I would look at it backward.
I'd keep the text entered as a string member in the control, so at all times I know what is actually entered in the control (like the Text property in a TextBox).
Then I would use the TextRenderer.MeasureText() method (http://msdn.microsoft.com/en-us/library/7sy6awsb.aspx) and I would keep measuring the length of the string repeatedly until I pass the X coordinate of the mouse within the control, right then I know how many characters are chosen.
For example, assume the user has the text Hello written in the control.
And the X coordinate hit right between the l and the o, which could be of value 20.
Then I would repeatedly calling MeasureText() on the following strings:
H: width of 5 pixels.
He: width of 10 pixels.
Hel: width of 14 pixels.
Hell: width of 17 pixels.
Hello: width of 22 pixels.
Then I know the mouse was hit between the l and the o, so I would then highlight the text Hell.
Sorry for the distasteful example =)
UPDATE:
You can optimize this a bit by calculating the lengths in a binary-search-tree-like fashion.
Just like you would look up a name in the phonebook, you don't look page by page, but rather split in half as you go along, getting closer and closer until it's definitely between these two pages.
Similarly, especially for long string values of the control, calculate the width of the entire string, then half its length, and split there. I think that would be O(n log n) at that point.
Of course it would be O(1) if the text is of fixed width =)
Another thing you can do to build upon BeemerGuy's great suggestion is to precalculate an array of offsets. As the string is changed (the user types or the property is set in code) you can recalculate the offset array. That will save you the call to MeasureFont on the mouse clicks and will make finding the character trivial. You basically iterate the array until you find the nearest character. Since the offsets are implicitly sorted by value you can even use a binary search to make it more effective.