I use WPF interoperability to host WPF user control inside WinForms form.
Everything works OK except ugly text rendering:
<Label Content="Normal text" Name="labelNormal"/>
<Label Content="Bold text" Name="labelBold" FontWeight="Bold" />
-- here is simple Labels on WPF Window:
WPF Window http://img525.imageshack.us/img525/7049/wpfwindow.png
-- and the same labels shown when the WPF user control is hosted in WinForms:
Interop variant is quite different: intercharacter interval is zero and the the text looks bolder that pure WPF variant. When normal text is acceptable, bold text is ugly.
Are there any ideas how to fix it?
Thank you in advance!
(edited Jan 18th to add that it's not just the font rendering mode, but also the font itself.)
There are two relevant factors here: the font, and the font formatting mode.
Your Windows Forms host application is imposing a default font family of "Microsoft Sans Serif" at a font size of 8.25pt, which in WPF's measurement units is a FontSize
of 11. But WPF will typically use a different font - I'm running Windows 7 with the default Aero theme, and WPF defaults to Segoe UI with a FontSize
of 12.
So the biggest reason you're seeing different results here is that those are two different fonts. Adding FontFamily="Segoe UI" FontSize="12"
to the UserControl
root element makes the two WPF examples look more consistent to me. (But this will of course make your WPF text look less consistent with text in the containing Windows Forms app. That's the whole reason the ElementHost
propagates the Windows Forms font choice into the WPF content.)
Before I edited this, I had thought that it might be down to the difference between the Ideal
and Display
modes for WPF text rendering. Having realised it's mainly about the font, I no longer think this is the case, but I'm going to leave the discussion of this other issue in here because it's still useful for anyone trying to get their WPF text to look consistent with their Windows Forms text. The default for WPF is Ideal
, but if you're running in a Windows Forms app, arguably Display
is better because that would make it look consistent with how Windows Forms normally renders things.
You can control this in WPF on a per-element basis by adding this:
TextOptions.TextFormattingMode="Display"
(or "Display"
depending on which mode you want). This attachable property was added in WPF v4, to let you choose between the scalable-but-slightly-blurry text rendering WPF has had since its first release, and the distorted-but-sharp grid fitting rendering that Win32 and GDI+ (and therefore Windows Forms) use. That will affect the element you apply it to, and also any descendants. (E.g., if you set this on a StackPanel
it should apply to all the elements in that panel, unless you also set it to a different value locally on the children.)
By default, WPF tries to maintain better fidelity to the original typeface design than Win32 or GDI+. And it also renders text in a way that means it scales consistently - increasing the font size by, say 12% will make the width of the text 12% larger on screen. That's not the case in Win32 or GDI+ where you get rather more complex non-linear changes.
But many people complained about the increase in bluriness you get in exchange for the better fidelity. So that's why WPF 4 introduced that new property. Set it to Display
to get the lower-fidelity but sharper old style rendering.
Since you can choose it on a per-element basis, you can pick whichever you like the look of independently for you bold and your normal text.
Yet another answer:
I found that it is also possible to change font type and size on the windows forms:
public partial class MyForm : Form
{
public MyForm()
{
InitializeComponent();
this.Font = new System.Drawing.Font(
"Segoe UI",
9,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point,
((byte)(0)));
}
}
This setting will transferred to host element too. So the windows form and the WPF will look similar and no changes to WPF-design is needed.