jpi*_*son 6 wpf mdi winforms-interop visual-artifacts
在WinForms MDI应用程序中托管WPF用户控件时,如果您有多个彼此重叠的表单会导致非常不同的可视化工件,则会出现绘图问题.将一个子窗体拖动到另一个子窗体之后,这些工件主要是可见的,这些窗体也承载WPF内容,或者允许子窗体的边缘在拖动它时由主MDI父窗体剪切.在完成子窗体的拖放操作后,工件一般会保持不变,但我发现将焦点设置到不同的应用程序窗口,然后重新聚焦到我的应用程序窗口,它重新绘制,并且一切都很好,直到孩子表格再次移动.请参阅下面的图片来说明问题.

那些在微软的人坚持认为WinForms MDI已经是MDI的充分解决方案,并且不需要重新发明WPF,尽管我发现很难相信他们尝试以这种方式创建WPF应用程序,因为它有明显的缺点.
更新:我遗漏的一些额外注释是,如果我创建这些表单而不设置MdiParent,它们将被创建为常规表单,并且不会发生此问题.此问题似乎是WinForms MDI方案所特有的.此外,我目前在Windows 7企业版上运行,我知道在Windows XP上结果可能会有很大差异,但我无法对此进行测试.
更新:我在这个问题上找到了一些我认为应该分享的其他相关资源.
似乎另一种解决方法是恢复软件渲染而不是利用硬件加速.这是Marco Zhou在MSDN论坛上提出的建议.
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
this.Loaded += delegate
{
var source = PresentationSource.FromVisual(this);
var hwndTarget = source.CompositionTarget as HwndTarget;
if (hwndTarget != null)
{
hwndTarget.RenderMode = RenderMode.SoftwareOnly;
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
我已经测试了这个,这个解决方案似乎工作得非常好,到目前为止,我找到了解决FoxPro互操作方案中这个问题的唯一解决方案,这个方案与我最初发布的WinForms非常相似.现在我打算在我的WinForms项目的MDI Parent解决方案上使用我原来的Refresh,但是对于我的其他本机互操作应用程序,例如当我的WPF控件托管在Visual FoxPro中时,我将使用此解决方案.当然,除非在任何一种情况下发现更优雅的解决方案.
另外值得注意的是,据我所知,软件渲染是XP系统上的唯一选择,通常Visual FoxPro nore WinForms通常利用原生WPF应用程序在Vista OS及更高版本上执行的相同类型的硬件加速.因此,当您必须处理互操作时,使用此选项可能没有听起来那么糟糕.目前我不知道使用此解决方案时有任何相关的副作用,但如果有任何相关的副作用将不得不认真考虑.
好吧,我可能已经找到了解决方案,尽管感觉有点像黑客。看起来,如果在移动子 MDI 窗体时调用 MDI 父级上的 Refresh 方法,则所记录的工件就会消失。从视觉上看,拖动窗口时事情显得有点紧张,但它似乎比我在原始帖子中展示的示例更容易接受。
private void Form1_Move(object sender, EventArgs e)
{
this.ParentForm.Refresh();
System.Diagnostics.Debug.WriteLine(string.Format("Form Moved to: ({0},{1})", this.Left, this.Top));
}
Run Code Online (Sandbox Code Playgroud)
我以同样的方式尝试了许多组合,例如通过调用Update()、Invalidate()、Refresh()等方法仅刷新正在移动的子窗口,并且我还在 MDI 父级上尝试了这些相同的方法以及我托管的 WPF 控件上的Dispatcher.Invoke(DispatcherPriority.Render, ...)和InvalidateVisual(),但这些其他方法都不能接受专门在 MDI 父级上调用Refresh() 。
我意识到这可能不是最佳解决方案,因为每次子窗口移动几个像素时我都会强制整个主应用程序窗口刷新,但就目前而言,这是我发现有效的唯一合理的解决方案。如果其他人有任何替代解决方案或对此有任何改进,我将很乐意接受您的答案。
| 归档时间: |
|
| 查看次数: |
5456 次 |
| 最近记录: |