I want to add a horizontal line to the RichTextBox as a delimiter of my text.
I've found some examples of RTF code implementing a line and tried them in that way:
rtbResFile.Rtf = #"{\rtf1{\pard some text.\par}{\pard \brdrb \brdrs \brdrw10 \brsp20 \par}{\pard \par}{\pard some other text.\par}}";
This way implements creating a blank paragraph with border, so that should looks like a line. However it doesn't show anything. Just a blank paragraph.
Even if I try to implement it in the way include line object
{\rtf1
{\pard some text.\par}
{\pard {\*\do\dobxcolumn\dobypara\dodhgt
\dpline\dpxsize9200\dplinesolid\dplinew30}\par}
{\pard some other text.\par}
}
It still shows nothing. Does RichTextBox supports this? Or any other ways include the horizontal line in the rtf string?
There are a few different ways to create a horizontal line in RTF. Depending on the control or program being used your mileage may vary. RTF implementations in controls and programs tend to simply ignore markup that they don't know how to deal with. Note that the code samples below are snippets and not complete RTF documents. They will need to be embedded in a valid RTF document to work.
By drawing polygons:
{\pard{\*\do
\dobxcolumn \dobypara \dodhgt7200
\dpline \dpptx0 \dppty0 \dpptx7200
\dppty0 \dpx0 \dpy0 \dpxsize7200
\dpysize0 \dplinew15
\dplinecor0 \dplinecog0 \dplinecob0 }\par}
By inserting a blank paragraph with a border followed by another blank paragraph without a border:
{\pard \brdrb \brdrs \brdrw10 \brsp20 \par}
{\pard\par}
You can change the size and apparent positionof the line by setting indents on the paragraph:
{\pard \li2268 \ri567
\brdrb \brdrs \brdrw10 \brsp20 \par}
{\pard\par}
I highly recommend O'Reilly's RTF Pocket Guide for working with this stuff, which is where this came from.
Some further experimentation produced the code below, which does work in WordPad and the RichTextBox control.
{\pict\wmetafile8\picw26\pich26\picwgoal20000\pichgoal15
0100090000035000000000002700000000000400000003010800050000000b0200000000050000
000c0202000200030000001e000400000007010400040000000701040027000000410b2000cc00
010001000000000001000100000000002800000001000000010000000100010000000000000000
000000000000000000000000000000000000000000ffffff00000000ff040000002701ffff0300
00000000
}
Basically, it involves inserting a 1x1 pixel image of a black dot and stretching it as needed by adjusting the height and width goals. The goal measurement is in twips. A twip is defined as being 1/1440 of an inch. It's a horrible hack, but it works.
Here is an example of the last snippet placed into a complete, valid RTF document that correctly displays on both WordPad and the RichTextBox control from Windows Forms:
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
{\*\generator Riched20 10.0.19041}\viewkind4\uc1
\pard\sa200\sl276\slmult1\f0\fs22\lang9 Above\par
{\pict\wmetafile8\picw26\pich26\picwgoal20000\pichgoal15
0100090000035000000000002700000000000400000003010800050000000b0200000000050000
000c0202000200030000001e000400000007010400040000000701040027000000410b2000cc00
010001000000000001000100000000002800000001000000010000000100010000000000000000
000000000000000000000000000000000000000000ffffff00000000ff040000002701ffff0300
00000000
}
\par
Below\par
}
This function creates a horizontal bar that's just a picture. To create this picture, I just copied a horizontal bar from Visio into an RTF textbox, and then viewed the underlying RTF. Thus, it's possible to insert any image in this manner.
The code below works by moving the cursor to the very end of the text, then setting the "selected" RTF to be the aforementioned bar image. The text is then unselected.
The code sets this bar to be centered, however by setting the centreText to an empty string (or just removing the code), left alignment will be maintained.
/// <summary>
/// Appends a horizontal bar at the end of the specified Rich Text Box
/// </summary>
/// <param name="rtb">Rich Text Box to which horizontal bar is to be added</param>
private void AppendHorizontalBar(RichTextBox rtb)
{
// Position cursor at end of text
rtb.Select(rtb.TextLength, 0);
int selStart = rtb.TextLength;
int selEnd = rtb.TextLength;
// Textbox may transform chars, so (end-start) != text.Length
rtb.Select(selStart, selEnd - selStart);
// This is the RTF section to add.
string horizontalBarRtf = #"{\pict\wmetafile8\picw12777\pich117\picwgoal7245\pichgoal60 0100090000035b00000004000800000000000400000003010800050000000b0200000000050000000c022100280e030000001e0008000000fa0200000300000000008000040000002d01000007000000fc020100000000000000040000002d010100080000002503020011001100170e110008000000fa0200000000000000000000040000002d01020007000000fc020000ffffff000000040000002d01030004000000f0010000040000002701ffff030000000000}";
string centreText = "\\pard\\qc"; // set this to empty string to keep existing text alignment
// Wrap to-add RTF section in RTF tag
rtb.SelectedRtf = String.Format("{{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033\\uc1 {0} {1} \\line}}", centreText, horizontalBarRtf);
// Leave no text selected
rtb.SelectionLength = 0;
}
Related
I have a Windows Forms project that sets button text based on variables. The font is quite large for readability, but it means that some words are too long to fit in the button nicely, and the last few characters break onto multiple lines.
Is there an algorithm or property I can use to resize the text inside the button to prevent this from happening?
I don't want to try to fit the text on one line, I just want to stop the text from splitting words up.
If you really want to resize the font, you could try to detect when the text has reached the bounds of the button and then reduce the font size. Here's some code to get you started, but I'm not sure how to determine the length where text will start wrapping based on the button width. Perhaps there's some other property for that which I couldn't find.
// Get some info from the button control
var graphics = button1.CreateGraphics();
var font = button1.Font;
var textWidth = graphics.MeasureString(button1.Text, font).Width;
// Not sure what the magic formula is to determine when the word wraps
if (textWidth > button1.Width - 25)
{
// Assign a new font based on the old one, but smaller
button1.Font = new Font(font.FontFamily, font.Size - 1,
font.Style, GraphicsUnit.Pixel);
}
Set the AutoSize of the button to "false":
Button1.AutoSize = "false"
white-space: -moz-pre-wrap; /* Firefox */
white-space: -o-pre-wrap; /* Opera */
white-space: pre-wrap; /* Chrome */
word-wrap: break-word; /* IE */
I am not sure, but there should not be any algorithm which can help you here (even AI algorithms). Constraint is you want to keep font size and button size same. However you can do following which could solve your problem.
Use abbreviated text. e.g. First few words(characters)/ Initials of text. Generally contacts list on android mobiles, skype, or any other communicator shows initials if avatar is not set.
Show some part of text on button and when mouse hovers then show full text by resizing the button or on tooltip.
Add some space on form which will show full text when mouse is hovered on any button on it. So a common label on form which will show full button text when mouse is hovered on any button.
If texts are fixed/static then introduce some icons on button instead of text and show full text as tooltip.
~Nilesh
I have a content control in word, let's call it docHeader. When the text inside that control gets long, the MSWord automatically continues from next line (wraps the text?). This causes some other controls to change their position, what I don't want.
My question is, is it possible to detect it somehow, that the control's value has multiple lines?
ContentControl contControl = document.GetDocumentContentControlByName("docHeader");
//Check if contControl.Value is longer than one line
//Probably also depends on font size, margins, etc.
//This is what I finally need:
contControl.HasMultipleLines();
Thank you.
I was creating a C# Console Application that fills in the details in a certificate template (pdf) file using ITextSharp. The text that needs to be filled is dynamically generated.
If the dynamically generated text exceeds a certain size the field name gets truncated. I have already thought of an algorithm to solve this problem for which I require the maximum number of characters that can be accommodated in a page with the given font and font-size. The width of the page where the text has to be accommodated is given to us already.
I used the following code:
string text = "This is the test string that needs to be accommodated";
// Registering a font
FontFactory.Register("somefont.ttf", "script");
var script = FontFactory.GetFont("script", 20f); // registers the font with the given type and size.
Phrase phrase_text = new Phrase();
phrase_text.Add(new Chunk(text, script));
ColumnText.ShowTextAligned(pbover, Element.ALIGN_CENTER, new Phrase(phrase_text), PageSize.A4.Height/2, 140, 0);
This code seems to work fine, but when I am adding a bigger text in the screen, the text gets truncated with the alignment still in the center (in the horizontal sense).
I was reading something on using the Graphics library, but could not resolve the issue.
You say that you are filling out a template. That assumes that you have at least one AcroForm field in your document. Filling out fields is explained in the answer to this question: itextsharp setting the stamper FormFlatttening=true results in no output
Usually, the field has a property that defines the font size that needs to be used, but you are right: if the text doesn't fit the rectangle defined by the form field, the text gets truncated. You can change this by setting the font size to "auto". This way, the font size will decrease if the text doesn't fit. This is explained here: Set AcroField Text Size to Auto
Or you could use a multiline field. See How to get the row count of a multiline field?
If you don't have a form field (which would be strange, because that means that you have to program the coordinates, e.g. PageSize.A4.Height/2, 140), you shouldn't use the showTextAligned() method. If there is no way you can define the location using a form field (but I can't think of any argument why you couldn't), you should take a look at the MovieAds example (taken from my book iText in Action).
I have a method AddParagraph that looks like this:
public bool AddParagraph(Paragraph p, PdfContentByte canvas,
AcroFields.FieldPosition f, bool simulate)
{
ColumnText ct = new ColumnText(canvas);
ct.SetSimpleColumn(
f.position.Left, f.position.GetBottom(2),
f.position.GetRight(2), f.position.Top
);
ct.AddElement(p);
return ColumnText.HasMoreText(ct.Go(simulate));
}
In this example, I create a ColumnText object for which I define a column. I add a paragraph, and I render that paragraph. If simulate is true, I don't add it for real, I add it virtually to see if the paragraph fits. If it fits, I call the method anew for real (with simulate = false).
I repeat this as many time as needed, decreasing the font with 0.2 user units at every try. Only if the font gets smaller than 6pt, I allow iText to truncate the content.
while (AddParagraph(CreateMovieParagraph(movie, size),
canvas, f, true) && size > 6)
{
size -= 0.2f;
}
I have a problem with character spacing.
Basically I have something like this which comes from a txt file:
****************
*System Details*
****************
Looks nice and uniform, however, when I open have this go into a RichTextBox this happens:
Irregular character spacing example:
I've tried all different properties to try and stretch it, render it etc. but nothing works.
The data is coming in from code-behind OpenDialogBox that stores all the lines of the file in a string[]. A foreach loop then sends the lines into the RTB. (It needs to be a loop as each line gets checked)
Any help it greatly appreciated!
Many thanks
This is most likely a font choice problem. By default WPF uses Segoe UI on Windows 7 and above which is a non-monospaced font. This means that each character will not necessarily take up the same amount of space as each other character leading to issues if you are trying to align characters between lines. The easiest way to get alignment to work is by changing the font to a monospaced font by setting the FontFamily property on the RichTextBox.
I am programmatically creating a FlowDocument, then translating it to Rich Text, so a user can edit it in a Rich Text box. I cannot figure out how to insert a horizontal line in the FlowDocument that will display across the whole width of the edit box (and subsequent rendered PDF).
I found this thread which (allegedly) shows how to do exactly what I want, in XAML:
Simple (I think) Horizontal Line in WPF?
And this one:
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/bcd334c7-8e2b-4e59-a344-4376b30cf847/
I have attempted to replicate this programmatically, like this:
Line pLine = new Line();
pLine.Stretch = Stretch.Fill;
pLine.Stroke = Brushes.Black;
pLine.X2 = 1;
para.Inlines.Add( pLine );
But, this ends up displaying nothing at all in the resulting RTF edit box. The rest of the Rich Text is there. Just no line at all.
I also tried creating a Table and inserting the text I want to come after the horizontal line into a cell. Then I set a custom border, just for the top of the Table. That gives me a horizontal line, but it doesn't go all the way across the screen (after it's converted to RTF and shown in the RTF edit box), and it doesn't show at all after I render it into a PDF.
I have resorted to the complete hack of just inserting a Run of 60 underscore ('_') characters and a LineBreak. That "works", but it sucks. Can anybody tell me how to do this correctly?
i am using this little monster to insert a line at the current cursor position in a RichTextBox.
var ruler = new Line { X1 = 0, Y1 = 0, X2 = 1000, Y2 = 0, Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 2 };
new InlineUIContainer(ruler, richtextbox.CaretPosition.GetInsertionPosition(LogicalDirection.Forward));
I think you forgot to set the StrokeThickness.
And even if you set Stretch.Fill your line is only one device independent unit long.
My experience with Otto's method was that it draws a nice horizontal line in the editor but the line is not saved in the RTF file. My handy little O'Reilly "RTF Pocket Guide" yielded a block of RTF that does both. Here is the click handler for my "Insert Line Break" toolbar button...
private void InsertLineBreak_Click(object sender, RoutedEventArgs e)
{
MemoryStream stream =
new MemoryStream(ASCIIEncoding.Default.GetBytes(#"{\pard\brdrb\brdrs\brdrw10\brsp20\par}"));
rtbEditor.Selection.Load(stream, DataFormats.Rtf);
}