Текст отображается по-разному в окне WPF и внутри ElementHost

Я использую совместимость WPF для размещения пользовательского контроля WPF внутри формы WinForms. Все работает хорошо, за исключением уродливого отображения текста:

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

- вот простые ярлыки в окне WPF:
Окно WPF http://img525.imageshack.us/img525/7049/wpfwindow.png

- и те же метки, которые отображаются, когда пользовательский элемент управления WPF размещен в WinForms:
WPF Interop

Вариант взаимодействия совсем другой: интервал между символами равен нулю, и текст выглядит более смелым, чем чистый вариант WPF. Когда нормальный текст приемлем, жирный текст уродлив.

Есть какие-нибудь идеи как это исправить?

Заранее спасибо!

Ответ 1

(отредактирован 18 января, чтобы добавить, что это не только режим рендеринга шрифтов, но и сам шрифт.)

Здесь есть два фактора: шрифт и режим форматирования шрифтов.

Ваше хост-приложение Windows Forms накладывает семейство шрифтов по умолчанию "Microsoft Sans Serif" с размером шрифта 8.25pt, который в единицах измерения WPF равен FontSize из 11. Но WPF обычно использует другой шрифт - Я запускаю Windows 7 с темой Aero по умолчанию, а WPF по умолчанию использует интерфейс Segoe с FontSize из 12.

Таким образом, самая большая причина, по которой вы видите разные результаты, состоит в том, что это два разных шрифта. Добавление FontFamily="Segoe UI" FontSize="12" к корневому элементу UserControl делает два примера WPF более похожими на меня. (Но это, конечно же, сделает ваш текст WPF менее согласованным с текстом в содержащем приложении Windows Forms. Вся эта причина: ElementHost распространяет выбор шрифта Windows Forms в содержимое WPF.)

Прежде чем я отредактировал это, я подумал, что это может быть разница между режимами Ideal и Display для визуализации текста WPF. Поняв это в основном о шрифте, я больше не думаю, что это так, но я собираюсь оставить обсуждение этой другой проблемы здесь, потому что он по-прежнему полезен для тех, кто пытается заставить их текст WPF выглядеть совместимым с их Windows Формирует текст. По умолчанию для WPF используется Ideal, но если вы работаете в приложении Windows Forms, возможно, Display лучше, потому что это будет выглядеть в соответствии с тем, как Windows Forms обычно делает вещи.

Вы можете управлять этим в WPF на основе каждого элемента, добавив это:

TextOptions.TextFormattingMode="Display"

(или "Display" в зависимости от того, какой режим вы хотите). Это прикрепляемое свойство было добавлено в WPF v4, чтобы вы могли выбирать между масштабируемым, но слегка размытым текстовым рендерингом WPF, имевшимся с момента его первого выпуска, и искаженным, но резким подбором сетки, который визуализировал Win32 и GDI + (и, следовательно, Windows Формы). Это повлияет на элемент, к которому вы его примените, а также любые потомки. (Например, если вы установите его на StackPanel, он должен применяться ко всем элементам этой панели, если вы также не устанавливаете его на другое значение локально на дочерних элементах.)

По умолчанию WPF пытается поддерживать лучшую точность исходной конструкции шрифтов, чем Win32 или GDI+. И он также отображает текст таким образом, который означает, что он масштабируется последовательно - увеличивая размер шрифта, скажем, 12% сделает ширину текста на 12% больше на экране. Это не относится к Win32 или GDI +, где вы получаете более сложные нелинейные изменения.

Но многие люди жаловались на увеличение размытости, которое вы получаете в обмен на лучшую верность. Итак, почему WPF 4 представил это новое свойство. Установите его Display, чтобы получить более низкую точность, но более резкое рендеринг старого стиля.

Поскольку вы можете выбрать его на основе каждого элемента, вы можете выбрать тот, который вам нравится, независимо от того, как вы выглядите жирным шрифтом и своим обычным текстом.

Ответ 2

Еще один ответ:

Я обнаружил, что также можно изменить тип и размер шрифта в окнах:

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

Этот параметр также будет перенесен в элемент host. Таким образом, форма Windows и WPF будут выглядеть одинаково, и никаких изменений в WPF-дизайне не требуется.