2017-07-28 90 views
1

所以我有一个噩梦试图在wpf webbrowser控件中运行ckeditor。我们公司正在为他们的网站使用的自定义内置ckeditor,会引发一个错误,指向任何地方..第0行,但它可以在其他地方使用,包括IE。基本包,半载,但抛出未定义的错误,并在加载阶段保持灰色。这是最新的ck编辑器4.7。 我已经尝试过使用版本3.6,根本没有任何反应,ckeditor抛出没有错误,但没有加载任何(在wpf浏览器以外的罚款)。ckeditor在WPF WebBrowser控件

这里是我注入wpfbrowser的一些基本的html代码。

  WebBrowser webBrowser = dependencyObject as WebBrowser; 
     if (webBrowser != null) 
     { 
      var html = "<head>" + 

         "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />" + 
         "<meta charset=\"UTF-8\">" + 

         // $"<script type=\"text/javascript\" src=\"{ResourceDir}MathJax\\MathJax.js?config=MML_HTMLorMML,default\"></script>" + 
         $"<script type=\"text/javascript\" src=\"{ResourceDir}ckeditor\\ckeditor.js\"></script>" + 
         $"<script type=\"text/javascript\" src=\"{ResourceDir}JavaScript\\essay.js\"></script>" + 
         // $"<link rel=\"stylesheet\" type=\"text/css\" href=\"{ResourceDir}\\CSS\\main.css\">" + 

         "</head>" + 

         "<body>" + 
         "   <form>\r\n" + 
         "   <textarea name=\"editor\" id=\"editor\" rows=\"10\" cols=\"80\">\r\n" + 
            $"Hello World!" + /*{e.NewValue}*/ 
         "   </textarea>\r\n" + 
         "  </form>"+ 
         " <button onclick=\"ReplaceEditor()\">Click me</button> " + 
         "</body>"; 

      webBrowser.NavigateToString(html); 

其他的javascript如MathJax等工作得很好,请忽略我建立HTML的方式,它现在不相关。

这是essay.js内容

function ReplaceEditor() { 
CKEDITOR.replace('editor'); 
} 
window.onerror = function (message, url, lineNumber) { 
    window.external.GetErrors(message, url, lineNumber); 
} 

捕捉错误犯规太多帮助,因为它返回同一行0字符0是网页浏览器会抛出的所有错误。任何帮助表示赞赏,从我读过的内容来看,应该像人们以前的工作一样工作。

+0

在那里。看看[this](https://stackoverflow.com/a/18333982/1768303)是否有帮助。 – Noseratio

+0

令人遗憾的是,问题仍然存在,而且这些注册表的调整,打破了我可怕的wpf webbrowser的其他解决方法,因此不得不撤消它们,并且宁愿不向注册表写任何东西,因为应用程序将在外部使用。 –

+0

我能够无忧无虑地使用CKEditor 4.5.x。注意它写入HKCU,所以不需要管理员权限。尽管如此,不能告诉以后的CKEditor版本。 – Noseratio

回答

1

我想我知道什么是错的,你使用的是NavigateToString,它产生了一个about:blank页面。这不适用于CKEditor,与基于file://的编辑器主页相同。你需要一个真正的http/https基于页面,这可能是因为从他们的CDN引用CKEditor的那样简单(一个非常可靠的亚马逊托管的一个):

<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset="utf-8"> 
     <title>CKEditor</title> 
     <script src="https://cdn.ckeditor.com/4.7.1/standard/ckeditor.js"></script> 
    </head> 
    <body> 
     <textarea name="editor1"></textarea> 
     <script> 
      CKEDITOR.replace('editor1'); 
     </script> 
    </body> 
</html> 

下面是简单的例子装载CKEditor Standard Editor Example到WPF WebBrowser控制,它对我来说没有任何问题。

如果您不能拥有自己的专用在线页面来托管CKEditor,则可能需要运行应用内单页网络服务器以通过http://localhost提供服务。有很多例子可以说明如何去做(例如this one)。

using Microsoft.Win32; 
using System; 
using System.Diagnostics; 
using System.Windows; 
using System.Windows.Controls; 

namespace WpfWebEditor 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     WebBrowser _webBrowser; 

     static MainWindow() 
     { 
      var fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName); 
      SetBrowserFeatureControlKey("FEATURE_BROWSER_EMULATION", fileName, GetBrowserEmulationMode()); 
     } 

     public MainWindow() 
     { 
      InitializeComponent(); 
      this.Loaded += MainWindow_Loaded; 

      _webBrowser = new WebBrowser(); 
      this.Content = _webBrowser; 
     } 

     private void MainWindow_Loaded(object sender, RoutedEventArgs e) 
     { 
      _webBrowser.Navigate("https://nightly.ckeditor.com/standard/samples/"); 
     } 

     private static void SetBrowserFeatureControlKey(string feature, string appName, uint value) 
     { 
      using (var key = Registry.CurrentUser.CreateSubKey(
       String.Concat(@"Software\Microsoft\Internet Explorer\Main\FeatureControl\", feature), 
       RegistryKeyPermissionCheck.ReadWriteSubTree)) 
      { 
       key.SetValue(appName, (UInt32)value, RegistryValueKind.DWord); 
      } 
     } 

     private static UInt32 GetBrowserEmulationMode() 
     { 
      int browserVersion = 7; 
      using (var ieKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer", 
       RegistryKeyPermissionCheck.ReadSubTree, 
       System.Security.AccessControl.RegistryRights.QueryValues)) 
      { 
       var version = ieKey.GetValue("svcVersion"); 
       if (null == version) 
       { 
        version = ieKey.GetValue("Version"); 
        if (null == version) 
         throw new ApplicationException("Microsoft Internet Explorer is required!"); 
       } 
       int.TryParse(version.ToString().Split('.')[0], out browserVersion); 
      } 

      UInt32 mode = 11000; // Internet Explorer 11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 Standards mode. Default value for Internet Explorer 11. 
      switch (browserVersion) 
      { 
       case 7: 
        mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control. 
        break; 
       case 8: 
        mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for Internet Explorer 8 
        break; 
       case 9: 
        mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for Internet Explorer 9. 
        break; 
       case 10: 
        mode = 10000; // Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 mode. Default value for Internet Explorer 10. 
        break; 
       default: 
        // use IE11 mode by default 
        break; 
      } 

      return mode; 
     } 
    } 
} 
+1

干杯,这实际上工作,虽然它不需要设置任何浏览器功能(虽然我可以看到这可能会有所帮助。不需要托管本地http页面。同样可以通过创建新的URI到本地html页面和导航到我正在考虑如果我应该写一个答案,或接受你的文章,我从来没有想到这个。 –

+0

@AistisTaraskevicius,很高兴它帮助我很惊讶地知道它对'file://起作用''也是基于页面的,我认为它没有做过几次CKE迭代,我敢肯定,我们尝试过,无论如何,随时发布一个详细的答案,以便其他人可以从中受益。 – Noseratio