我有一个 winforms 应用程序(嗯,它是一个在 Outlook 中运行的 VSTO Outlook 插件),我在其中使用工具栏,并在该工具栏中通过使用 ElementHost 容器嵌入了 WPF 用户控件。
如果我每次更改某些显示设置(例如屏幕分辨率和/或比例)时都重新启动它,我的应用程序非常适合不同的屏幕分辨率和/或比例因子。
但是现在我有以下两个问题:
在这两种情况下,我都遇到渲染问题:在控件边缘神奇地绘制了一些黑线,请参见下面的一些屏幕截图(您在顶部看到的标题为“我的自定义 CTP”的工具栏是 VSTO Outlook 控件这迫使我嵌入 winforms 用户控件,所以我这样做:Winforms 用户控件 <---> ElementHost <----> Wpf 用户控件):
我的 SVG 图像也是使用路径绘制的,而且我的所有 TextBlock 都显得模糊。
我尝试过不同的尝试但没有成功。
尝试#1:
仅按照此处的说明使用软件渲染。在我的 WPF 用户控件中,在构造函数视图中的 InitializeComponent 之后,我执行以下操作:
public myWpfView()
{
InitializeComponent();
if (ForceSoftwareRendering)
RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
}
public bool ForceSoftwareRendering
{
get
{
int renderingTier = (System.Windows.Media.RenderCapability.Tier >> 16);
return renderingTier == 0;
}
}
尝试#2: 在我的 Wpf 用户控件构造函数中,我订阅 DisplaySettingsChanged 事件来检测显示设置更改,并在处理程序中执行一些无效操作,然后立即更新布局。再次没有成功:
public myWpfView()
{
InitializeComponent();
Microsoft.Win32.SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}
private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
this.VisualBitmapScalingMode = BitmapScalingMode.NearestNeighbor;
this.VisualClearTypeHint = ClearTypeHint.Enabled;
this.VisualEdgeMode = EdgeMode.Unspecified;
this.VisualTextHintingMode = TextHintingMode.Auto;
this.VisualTextRenderingMode = TextRenderingMode.ClearType;
this.UseLayoutRounding = true;
this.SnapsToDevicePixels = true;
this.InvalidateVisual();
this.InvalidateMeasure();
this.InvalidateArrange();
this.UpdateLayout();
}
看起来在更改屏幕分辨率和/或比例后,需要更新 wpf 用户控件的布局或类似的内容,以便重新调整而无需重新启动它,所以这正是我在上面的 SystemEvents_DisplaySettingsChanged 事件处理程序指示但没有成功。也许我错过了一些东西,我不知道......
附加说明: 我正在使用 AutoScaleMode = dpi。也尝试过字体。
我建议首先确保您的 WPF 视觉对象本身具有 SnapsToDevicePixels=true。
WinForms 应用程序中的最大风险是它们并不真正了解可扩展性,并且可能会要求 WPF 提供固定像素大小的“图像”(认为 WPF“冻结”视觉对象),然后由 WinForms 应用程序缩放以适应可用空间。听起来这就是您所得到的,并且这是 WinForms 应用程序的限制。