zoukankan      html  css  js  c++  java
  • DockPanel与GeckoFX、ChrominumFX、CefSharp结合使用问题

    在使用DockPanel与ChrominumFx时,当在以下条件下拖动窗体时,会发生ChromiumWebBrowser崩溃的情况,此种情况也会在DockPanel与GeckoFX或CefSharp结合使用时出现。

    出现条件:

    1. 当Form表单初始时以DockState.Document,然后拖动此表单到非DockState.Document模式时,可以是DockState.Left、DockState.Right或其他。
    2. 当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);
    };
    

    至此,可解决浏览器控件崩溃问题。

  • 相关阅读:
    postgresql postgres.Jsonb
    gorm jsonb
    json
    postgresql重置序列和自增主键
    go build x509: certificate has expired or is not yet valid
    权限修饰符
    交换两个变量的值
    Java编译报错:编码GBK的不可映射字符
    原码反码补码的理解
    Scanner类中hasNext()方法的解析
  • 原文地址:https://www.cnblogs.com/lyyxjc/p/7073853.html
Copyright © 2011-2022 走看看