文本在WPF窗口和ElementHost内部呈现不同

时间:2011-01-13 10:44:52

标签: wpf elementhost

我使用WPF互操作性来在WinForms表单中托管WPF用户控件。 一切正常,除了丑陋的文字渲染:

    <Label Content="Normal text" Name="labelNormal"/>
    <Label Content="Bold text" Name="labelBold" FontWeight="Bold" />

- 这是WPF窗口上的简单标签:
WPF Window http://img525.imageshack.us/img525/7049/wpfwindow.png

- 以及在WinForms中托管WPF用户控件时显示的相同标签:
WPF Interop http://i51.tinypic.com/14j4xnc.jpg

Interop变体是完全不同的:字符间间隔为零,文本看起来更纯粹的纯WPF变体。当普通文本可以接受时,粗体文本很难看。

有任何想法如何修复它?

提前谢谢!

2 个答案:

答案 0 :(得分:19)

(1月18日编辑,补充说它不仅仅是字体渲染模式,还有字体本身。)

这里有两个相关因素:字体和字体格式化模式。

您的Windows窗体主机应用程序强加了一个字体大小为8.25pt的默认字体系列“Microsoft Sans Serif”,在WPF的测量单位中为FontSize为11.但WPF通常会使用不同的字体font - 我使用默认的Aero主题运行Windows 7,WPF默认使用Segoe UI,FontSize为12。

所以你在这里看到不同结果的最大原因是那些是两种不同的字体。将FontFamily="Segoe UI" FontSize="12"添加到UserControl根元素会使两个WPF示例看起来更加一致。 (但这当然会使您的WPF文本看起来与包含Windows窗体应用程序中的文本不一致。这就是ElementHost将Windows窗体字体选择传播到WPF内容的全部原因。)

在我编辑之前,我曾认为可能是由于WPF文本呈现的IdealDisplay模式之间存在差异。已经意识到它主要是关于字体,我不再认为是这种情况,但我将在这里留下对这个问题的讨论,因为它对于任何试图让他们的WPF文本看起来与他们的Windows一致的人仍然有用表格文字。 WPF的默认值为Ideal,但如果您在Windows窗体应用程序中运行,可以说Display更好,因为这样可以使其与Windows窗体通常呈现的内容保持一致。

您可以通过添加以下内容在每个元素的基础上在WPF中控制它:

TextOptions.TextFormattingMode="Display"

(或"Display"取决于您想要的模式)。 WPF v4中添加了这个可附加属性,让您可以选择WPF自首次发布以来的可缩放但略微模糊的文本渲染,以及Win32和GDI +的扭曲但非常锐利的网格拟合渲染(以及Windows表格)使用。这将影响您应用它的元素,以及任何后代。 (例如,如果你在StackPanel上设置它,它应该适用于该面板中的所有元素,除非你还在子节点上将它们设置为不同的值。)

默认情况下,WPF尝试保持比Win32或GDI +更好的原始字体设计保真度。并且它还以一种方式呈现文本,这意味着它可以一致地扩展 - 增加字体大小,比如12%将使文本的宽度在屏幕上增大12%。在Win32或GDI +中并非如此,在这种情况下,您会得到相当复杂的非线性变化。

但是很多人抱怨你获得的模糊度增加以换取更好的保真度。这就是WPF 4引入新属性的原因。将其设置为Display以获得较低保真度但更清晰的旧样式渲染。

由于您可以在每个元素的基础上进行选择,因此您可以选择独立的大胆外观和普通文本。

答案 1 :(得分:0)

又一个答案:

我发现在Windows窗体上也可以更改字体类型和大小:

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)));
  }
}

此设置也将传输到主机元素。所以windows窗体和WPF看起来很相似,不需要对WPF设计进行任何更改。