DockPanel與GeckoFX、ChrominumFX、CefSharp結合使用問題
阿新 • • 發佈:2017-06-24
ble static bject == tin default chang itl left
在使用DockPanel與ChrominumFx時,當在以下條件下拖動窗體時,會發生ChromiumWebBrowser崩潰的情況,此種情況也會在DockPanel與GeckoFX或CefSharp結合使用時出現。
出現條件:
- 當Form表單初始時以DockState.Document,然後拖動此表單到非DockState.Document模式時,可以是DockState.Left、DockState.Right或其他。
- 當Form表單初始時以非DockState.Document時,然後拖動此表單到DockState.Document模式時
條件總結:即DockState.Document與其他模式切換時,會出現瀏覽器控件崩潰的情況。
出現此問題原因是DockPanel動態改變了Form表單的MdiParent,嚴格來說,並不是DockPanel的問題,如果直接使用Winform的MDI窗口模式,只要改變Form表單的MdiParent,也會導致瀏覽器控件崩潰。
為什麽出現這個原因,目前並未深入分析,主要是也不知道從哪裏開始分析,因為只是使用GeckoFX、ChrominumFX、CefSharp第三方瀏覽器控件才會出現此問題,而.NET 自帶的WebBrowser沒有此問題。
解決辦法:
修改DockPanel部分源碼,核心思路是在設置MdiParent之前,把瀏覽器控件從Form表單移除,設置之後,再把瀏覽器控件加入Form表單。
修改源碼地方(修改的DockPanel版本是:2.13):
在DockContentHandler.CS類中 1053行之後,增加如下代碼:
1 private static readonly object MdiParentChangingEvent = new object(); 2 /// <summary> 3 /// 開始設置MdiParent之前事件 4 /// </summary> 5 public event EventHandler MdiParentChanging 6{ 7 add { Events.AddHandler(MdiParentChangingEvent, value); } 8 remove { Events.RemoveHandler(MdiParentChangingEvent, value); } 9 } 10 protected virtual void OnMdiParentChanging(EventArgs e) 11 { 12 EventHandler handler = (EventHandler)Events[MdiParentChangingEvent]; 13 if (handler != null) 14 handler(this, e); 15 } 16 17 private static readonly object MdiParentChangedEvent = new object(); 18 /// <summary> 19 /// 設置MdiParent之後的事件 20 /// </summary> 21 public event EventHandler MdiParentChanged 22 { 23 add { Events.AddHandler(MdiParentChangedEvent, value); } 24 remove { Events.RemoveHandler(MdiParentChangedEvent, value); } 25 } 26 protected virtual void OnMdiParentChanged(EventArgs e) 27 { 28 EventHandler handler = (EventHandler)Events[MdiParentChangedEvent]; 29 if (handler != null) 30 handler(this, e); 31 }
修改 DockContentHandler.CS類 785行的SetPane方法
1 private void SetPane(DockPane pane) 2 { 3 if (pane != null && pane.DockState == DockState.Document && DockPanel.DocumentStyle == DocumentStyle.DockingMdi) 4 { 5 if (Form.Parent is DockPane) 6 SetParent(null); 7 if (Form.MdiParent != DockPanel.ParentForm) 8 { 9 FlagClipWindow = true; 10 OnMdiParentChanging(EventArgs.Empty); 11 // The content form should inherit the font of the dock panel, not the font of 12 // the dock panel‘s parent form. However, the content form‘s font value should 13 // not be overwritten if it has been explicitly set to a non-default value. 14 if (PatchController.EnableFontInheritanceFix == true && Form.Font == Control.DefaultFont) 15 { 16 17 Form.MdiParent = DockPanel.ParentForm; 18 //Form.MdiParent = null; 19 Form.Font = DockPanel.Font; 20 } 21 else 22 { 23 Form.MdiParent = DockPanel.ParentForm; 24 //Form.MdiParent = null; 25 } 26 OnMdiParentChanged(EventArgs.Empty); 27 } 28 } 29 else 30 { 31 FlagClipWindow = true; 32 if (Form.MdiParent != null) 33 { 34 OnMdiParentChanging(EventArgs.Empty); 35 Form.MdiParent = null; 36 OnMdiParentChanged(EventArgs.Empty); 37 } 38 if (Form.TopLevel) 39 Form.TopLevel = false; 40 SetParent(pane); 41 } 42 }
修改DockContent.CS類,在317行以後增加:
1 private static readonly object MdiParentChangingEvent = new object(); 2 /// <summary> 3 /// 開始設置MdiParent之前事件 4 /// </summary> 5 public event EventHandler MdiParentChanging 6 { 7 add { Events.AddHandler(MdiParentChangingEvent, value); } 8 remove { Events.RemoveHandler(MdiParentChangingEvent, value); } 9 } 10 protected virtual void OnMdiParentChanging(EventArgs e) 11 { 12 EventHandler handler = (EventHandler)Events[MdiParentChangingEvent]; 13 if (handler != null) 14 handler(this, e); 15 } 16 17 private static readonly object MdiParentChangedEvent = new object(); 18 /// <summary> 19 /// 設置MdiParent之後的事件 20 /// </summary> 21 public event EventHandler MdiParentChanged 22 { 23 add { Events.AddHandler(MdiParentChangedEvent, value); } 24 remove { Events.RemoveHandler(MdiParentChangedEvent, value); } 25 } 26 protected virtual void OnMdiParentChanged(EventArgs e) 27 { 28 EventHandler handler = (EventHandler)Events[MdiParentChangedEvent]; 29 if (handler != null) 30 handler(this, e); 31 } 32 33 private void DockHandler_MdiParentChanging(object sender, EventArgs e) 34 { 35 OnMdiParentChanging(e); 36 } 37 private void DockHandler_MdiParentChanged(object sender, EventArgs e) 38 { 39 OnMdiParentChanged(e); 40 }
在 DockContent.CS類 14 行以後增加:
1 m_dockHandler.MdiParentChanging += new EventHandler(DockHandler_MdiParentChanging); 2 m_dockHandler.MdiParentChanged += new EventHandler(DockHandler_MdiParentChanged);
最後,在你的Form表單構造函數那裏增加:
this.MdiParentChanging += (o, e) => { this.Controls.Remove(this.MainWebBrowser); }; this.MdiParentChanged += (o, e) => { this.Controls.Add(this.MainWebBrowser); };
至此,可解決瀏覽器控件崩潰問題。
DockPanel與GeckoFX、ChrominumFX、CefSharp結合使用問題