WPF Web 浏览器控件中的 ckeditor
ckeditor in WPF WebBrowser Control
所以我在尝试 运行 wpf webbrowser 控件中的 ckeditor 时遇到了噩梦。我们公司在其网站上使用的自定义构建的 ckeditor 会抛出指向任何地方的错误.. 第 0 行,但它在其他任何地方都有效,包括 IE。基本包,半加载,但抛出未定义的错误并在加载阶段保持灰色。这是最新的 ck 编辑器 4.7。
我试过使用 3.6 版,但没有任何反应,ckeditor 没有抛出任何错误,但也没有加载(在 wpf 浏览器之外工作正常)。
这是我注入 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);
}
捕获错误并没有太大帮助,因为它 returns 网络浏览器针对所有错误抛出的同一行 0 字符 0。感谢任何帮助,从我读过的内容来看,它应该像人们以前让它工作的那样工作。
我想我知道出了什么问题,您正在使用 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,您可能需要 运行 一个应用程序内单页 Web 服务器通过 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;
}
}
}
所以我在尝试 运行 wpf webbrowser 控件中的 ckeditor 时遇到了噩梦。我们公司在其网站上使用的自定义构建的 ckeditor 会抛出指向任何地方的错误.. 第 0 行,但它在其他任何地方都有效,包括 IE。基本包,半加载,但抛出未定义的错误并在加载阶段保持灰色。这是最新的 ck 编辑器 4.7。 我试过使用 3.6 版,但没有任何反应,ckeditor 没有抛出任何错误,但也没有加载(在 wpf 浏览器之外工作正常)。
这是我注入 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);
}
捕获错误并没有太大帮助,因为它 returns 网络浏览器针对所有错误抛出的同一行 0 字符 0。感谢任何帮助,从我读过的内容来看,它应该像人们以前让它工作的那样工作。
我想我知道出了什么问题,您正在使用 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,您可能需要 运行 一个应用程序内单页 Web 服务器通过 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;
}
}
}