Paragraph formatting in a WPF RichTextBox? - wpf

I need to apply paragraph formatting to a selection in a rich text box. My RTB will behave the same way as the rich text boxes on StackOverflow--the user can type text into the RTB, but they can also enter code blocks. The RTB will apply very simple formatting to the code block--it will change the font and apply a background color to the entire block, similar to what you see in the code block below.
Changing the font is pretty straightforward:
var textRange = new TextRange(rtb.Selection.Start, rtb.Selection.End);
textRange.ApplyPropertyValue(TextElement.FontFamilyProperty, "Consolas");
textRange.ApplyPropertyValue(TextElement.FontSizeProperty, 10D );
Now I need to apply some paragraph-level formatting. I need to set the paragraph margin to 0, so I don't get a blank line between code lines, and I need to set the paragraph background color. Here's my problem: I can't figure out how to get the paragraph elements from the selection, so that I can apply formatting.
Any suggestions? An example of how to apply the Margin and Background properties would be incredibly helpful. Thanks!

Oh, that was easy.. Came across the answer with a little more research:
var textRange = new TextRange(TextBox.Selection.Start, TextBox.Selection.End);
textRange.ApplyPropertyValue(TextElement.FontFamilyProperty, "Consolas");
textRange.ApplyPropertyValue(TextElement.FontSizeProperty, 10D );
textRange.ApplyPropertyValue(Paragraph.MarginProperty, new Thickness(0));
textRange.ApplyPropertyValue(Paragraph.BackgroundProperty, "LightSteelBlue");
The only limitation is that the highlighting still extends only as far as the text, rather than to the right side of the control. I'll leave this question open for a couple of days; if someone can tell me how to extend the background to the right edge of the control, I'll accept your answer to this question.

Related

Multiline Textbox Vertical Spacing (Winform)

I am using the standard textbox control on a Windows form. I want to display the text VERTICALLY rather than horizontally. To accomplish this I set the multiline property to true, the TextAligh property to center and used the lines property to input each character as a separate array element. So far, so good.
I see the text displayed the way I want but would like to reduce the vertical spacing between lines without reducing the font size. Can it be done? If so, how?
It can be done, but not by the default options on a standard textbox.
You would probably need to override the Paint event and draw the text yourself, but it would get very ugly, and would essentially be reinventing the standard Paint method.

RichTextBox SelectionFont is unexpectedly *not* null

I'd like to change the font size of a chunk of RTF without erasing the bold / italic / underline formatting (an issue similar to the one in this question). The accepted answer is to modify the selection of the text box until the SelectionFont propery is null in order to find runs of consistently formatted text which can be modified individually. Sounds reasonable. However the actual behavior of the RichTextBox control seems to be inconsistent with the documentation.
In the documentation for RichTextBox.SelectionFont MSDN states:
If the current text selection has more than one font specified, this
property is null.
However, this code which uses mixed bold / regular text doesn't behave as you'd expect:
var rtb = new RichTextBox {
Rtf = #"{\rtf1 This is \b bold\b0.}"
};
rtb.SelectAll();
// Now you'd expect rtb.SelectionFont to be null,
// but it actually returns a Font object
Is there any other reliable way of formatting the text so that I can change the font size without clobbering the other formatting. (Manipulating the RTF directly is OK, I'm not absolutely set on using WinForms to achieve this).
I've given up on trying to go through Winforms to fix this. As I'm applying the change to a whole document (rather than just one portion), it turns out that it's not too hard to modify the RTF directly.
In this case I'm interested in the font size, which is represented by the \fs command. So to replace all the 8.5pt text with 10pt text, you can replace \fs17 with \fs20. (Yes, RTF font sizes come in units of half a point, apparently).
This seems to work well enough, although it does feel like one of those "let's mangle our HTML using regular expressions" type solutions, so I'm not convinced that it's very robust.
Take a look at this:
Changing font for richtextbox without losing formatting
I think it's the same issue. LarsTech's solution is working perfectly for me.

Winforms semi-transparent PNG over semi-transparent PNG

I think I must be missing something obvious, but I'm unable to find this after several hours of searching. Is there no way to use a PictureBox or other control to contain an image with partial transparent/alpha-blended pixels, and place that over another image and have the blending be based on the image under it?
For example, this produces the results I want:
Place a panel on a form.
Add an OnPaint handler.
In the OnPaint handler draw 1 PNG, then draw another PNG over it, using Graphics.DrawImage for both.
This does not:
Place a PictureBox on a form and set it to a PNG.
Place another PictureBox on the form and set it to a PNG.
Place the 2nd picture box over the first.
...even if the 2nd picture box is just empty and has a background color of Transparent, it still covers the picture below it.
I've read this stems from all winform controls being windows, so by nature they aren't transparent.
...but even the 15 year old platform I'm migrating from, Borland's VCL, had several windowless controls, so it's hard to imaging winforms doesn't at least have some easy solution?
My first example above is one answer, true, but that adds a lot of work when you can only use one big panel and draw all of your "controls" inside of it. Much nicer if you can have separate controls with separate mouse events/etc. Even if not an image control, and a control I have to draw myself, that would be fine, as long as I can just put one image in each control. In VCL they called this a "paint box", just a rectangle area you could place on a form and draw whatever you want on it. Has it's own mouse events, Bounds, etc. If you don't draw anything in it, it is like it's not even there (100% transparent) other than the fact it still gets mouse events, so can be used as a "hot spot" or "target" as well.
The PictureBox control supports transparency well, just set its BackColor property to Transparent. Which will make the pixels of its Parent visible as the background.
The rub is that the designer won't let you make the 2nd picture box a child of the 1st one. All you need is a wee bit of code in the constructor to re-parent it. And give it a new Location since that is relative from the parent. Like this:
public Form1() {
InitializeComponent();
pictureBox1.Controls.Add(pictureBox2);
pictureBox2.Location = new Point(0, 0);
pictureBox2.BackColor = Color.Transparent;
}
Don't hesitate to use OnPaint() btw.
Sorry, I just found this... once I decided to Google for "winforms transparent panel" instead of the searches I was doing before, the TransPictureBox example show seems to do exactly what I need:
Transparency Problem by Overlapped PictureBox's at C#
Looks like there are 2 parts to it:
Set WS_EX_TRANSPARENT for the window style
Override the "draw background" method (or optionally could probably make the control style Opaque).

Formatting specifc lines of text in WPF RichTextBox

In a WPF .NET 4.0 RichTextBox with the following text:
Apple
Cheese
Orange
Pear
Chicken
How would I programmatically with C#, (not with XAML markup), bold all lines that start with the character "C"?
More generally, how do you get a reference to a given line of text from a RichTextBox and then apply some formatting to it?
Well that was trickier than I expected but I think the code below does it:
foreach (var paragraph in richTextBox1.Document.Blocks)
{
var text = new TextRange(paragraph.ContentStart,
paragraph.ContentEnd).Text;
paragraph.FontWeight = text.StartsWith("C") ?
FontWeights.Bold : FontWeights.Normal;
}
Basically, the RichTextBox holds its content in a FlowDocument (accessed through the Document property), which in turn has a collection of Blocks containing each Paragraph. Actually, each item in the Blocks collection can be anything derived from the abstract class Block...but I'm assuming if you only ever add simple text to your RichTextBox then they'll always just be Paragraphs. See here for a better explanation!
The trickiest part is that to get the text out of the paragraph you need to use the TextRange class...but the good news is that, once we have the text, the Paragraph has simple properties on it for setting the font weight, etc!

Setting the ToolTip in a WPF chart?

I would like to set the ToolTip on my chart line, pie, area, bubble to include both the X and the Y values.
Charting is use is defined here :
xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
I've learned that I can use the ControlTemplate to do this and by overriding the entire thing, I can also set the tooltip.
But this also changes things which I like, the random color selection, the status changes etc.
Is there a way to apply only the tooltip binding to all chart series types, without having to override the entire thing for each of the types (that makes for a very long and mostly irrelevant code, which mostly I don't understand and don't care about)
Thanks! (My first post)
...
You have to copy a part of the original source (the style).
Check this site: http://blogs.msdn.com/b/delay/archive/2010/04/22/nobody-likes-a-show-off-today-s-datavisualizationdemos-release-includes-new-demos-showing-off-stacked-series-behavior.aspx
Here you can download this zip file that contains an example project in WPF.
Read the source/style in ChartStyling.xaml and your question will most likely be answered!

Resources