2010-04-07 63 views
6

當在WinForms MDI應用程序內託管WPF用戶控件時,如果有多個表單相互重疊而導致截然不同的視覺工件,則會出現繪圖問題。這些工件在將一個子窗體拖到另一個也承載WPF內容的子窗體上或通過允許子窗體的邊緣被拖動時由主MDI父窗口裁剪後大多可見。在完成子表單的拖放操作後,工件總是保持不變,但是我發現將焦點設置到不同的應用程序窗口,然後重新將焦點重新集中到我的應用程序窗口上,重新繪製並重新繪製,直到孩子再次出現爲止。表格再次移動。請參閱下面的圖像來演示問題。如何在WinForms MDI應用程序中託管WPF用戶控件時避免視覺工件?

Screenshot of described artifacts

那些在微軟堅持認爲的WinForms MDI已經是MDI足夠的解決方案,不需要在WPF重塑雖然我很難相信他們試圖創建一個WPF應用程序這種方式,因爲的缺點明顯。

更新:我遺漏了一些額外的筆記,如果我創建這些表單而不設置MdiParent,它們被創建爲常規形式,並且不會發生此問題。對於WinForms MDI方案,此問題似乎是唯一的。此外,我目前正在Windows 7 Enterprise上運行,並且我知道Windows XP上的結果可能會非常不同,但我無法對此進行測試。

更新:我在這個問題上發現了一些其他相關資源,我想我應該分享。

回答

2

好吧,我可能已經找到了解決辦法,雖然感覺就像一個黑客攻擊的一位。看起來,如果您在移動子MDI表單時調用MDI父級的刷新方法,那麼指出的工件就會消失。在拖動窗口時,視覺上的東西顯得有點緊張,但似乎比我在原始文章中展示的例子更可接受。

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

我試圖在同一靜脈)的多種組合,如清爽的剛子窗口正在被調用方法移動如更新()的Invalidate()刷新(我也試過這些相同的方法在MDI父級以及Dispatcher.Invoke(DispatcherPriority.Render,...)InvalidateVisual()在我託管的WPF控件上,但沒有任何其他方法可以接受撥打刷新()具體在M上DI父母。

我意識到這可能不是最佳解決方案,因爲我迫使整個主應用程序窗口在每次子窗口移動幾個像素時進行刷新,但就目前而言,這是唯一合理的解決方案,我發現作品。如果其他人有任何替代解決方案或任何改進,我會很樂意接受你的答案。

8

看來,另一個解決方法是恢復到軟件渲染,而不是利用硬件加速。這是MSDN論壇上的suggestion by Marco Zhou

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

我測試過這一點,這個解決方案似乎工作非常好,到目前爲止,我已經找到了解決一個FoxPro互操作的情況,這是非常類似的WinForms一個我在這個問題的唯一解決方案最初發布。現在我打算在我的WinForms項目中使用MDI Parent解決方案上的原始刷新,但對於其他本機互操作應用程序(例如當我的WPF控件託管在Visual FoxPro中時),我將使用此解決方案。這是當然,除非發現任何一種情況下更優雅的解決方案。

此外,重要的是要注意,從我所知道的軟件渲染是XP系統上的唯一選項,通常Visual FoxPro nore WinForms通常利用與本機WPF應用程序在Vista操作系統上執行的相同類型的硬件加速,向上。所以使用這個選項可能並不像聽起來當你不得不處理interop時那樣糟糕。目前我在使用這種解決方案時沒有意識到任何相關的副作用,但是如果有任何問題需要認真考慮。

2

檢查視頻驅動程序並嘗試禁用硬件加速。大多數工件是由壞的驅動程序,視頻卡故障或沒有足夠的時間來完成刷新引起的。

首先故障排除步驟:更新視頻驅動程序。很明顯,我知道。

我有類似的問題,檢查我的視頻卡設置(NVidia控制面板)顯示全局設置設置非常高,造成更長的刷新間隔,如果花費太長時間可能會中止。將我的設置恢復爲默認值可解決大部分問題。但是我也運行使用GPU的散列程序,所以這很可能是我現在很少發現的遺留問題的原因,並且大多數情況下它在Visual Studio中顯示出其醜陋的表情。

我遇到的另一個故障排除步驟是禁用WPF的硬件加速,這可以在'HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avalon.Graphics'中完成,或者應用程序可以做到這一點,但這僅用於故障排除;從不在應用程序中設置它們,因爲它將禁用所有WPF應用程序。我沒有這個註冊表設置,也沒有添加它,所以我不確定它的成功與否,但很多人說這解決了他們的問題。另請注意,某些應用程序可以使用此選項,如果可用,請嘗試禁用它。

另一個故障排除步驟是確保顯卡適合渲染的層級。任何支持DX9或更高版本的卡片都應該足夠,但其他因素(如我的情況)只是因爲它在列表中並不意味着它足夠滿足您的目的。

最後,您可以使用Visual Profiler(Windows SDK的一部分)和其他工具來幫助確定WPF缺乏與圖形處理能力相關的性能的更精確的情況。

渲染層級筆記和WPF的性能信息 - >http://msdn.microsoft.com/en-us/library/vstudio/ms742196(v=vs.90).aspx

希望這可以幫助別人。

- 瑞士斯特拉斯堡

0

您的用戶控件或窗口加載事件;

this.WindowState = System.Windows.WindowState.Minimized; 

this.WindowState = System.Windows.WindowState.Normal; 

它可能看起來不好解決方案。無需將頭靠在牆上。

土耳其諺語說:最好的代碼是代碼正在運行:)

相關問題