CefSharp 忽略使用 RequestContext 设置的首选项(拼写检查)

CefSharp ignores Preferences set with RequestContext (Spellcheck)

我尝试为 CefSharp Chromium 嵌入式浏览器(使用 NuGet 安装的 v3.3396.1786)和 CefSharp.WPF 组件 (v67) 启用拼写检查。我可以使用一种语言进行拼写检查,但我无法在运行时更改字典以进行拼写检查。我尝试了显示和链接的示例 on CefSharps github page 但没有成功。

无论我用 RequestContext.SetPreference()

设置什么,我的 CefSharp 浏览器总是使用 Locale 来确定用于拼写检查的语言

这是我初始化 Cef 的代码:

public static void Initialize()
{
    var settings = new CefSettings
    {
        BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase,
            Environment.Is64BitProcess ? "x64" : "x86",
            "CefSharp.BrowserSubprocess.exe"),
        Locale = "de-DE",
        RemoteDebuggingPort = 8088,
    };

    // Set BrowserSubProcessPath based on app bitness at runtime

    // Make sure you set performDependencyCheck false
    Cef.Initialize
    (
        settings,
        performDependencyCheck: false,
        browserProcessHandler: null
    );
    CefSharpSettings.LegacyJavascriptBindingEnabled = true;
}

实际浏览器是用另一种方法设置和创建的:

private void create_web_browser()
{
    current_web_browser = new ChromiumWebBrowser
    {
        Visibility = Visibility.Hidden,
        BrowserSettings = new BrowserSettings
        {
            FileAccessFromFileUrls = CefState.Enabled,
            UniversalAccessFromFileUrls = CefState.Enabled,
            Javascript = CefState.Enabled,
            ImageLoading = CefState.Enabled,
            JavascriptAccessClipboard = CefState.Enabled,
            JavascriptCloseWindows = CefState.Enabled,
            JavascriptDomPaste = CefState.Enabled
        }           
    };

    current_helper = new ChromiumObjectForScriptingHelper(web_browser_ready_async, current_web_browser);
    if (ToolbarConfig != null)
    {
        current_helper.SetToolbarConfig(ToolbarConfig);
    }
    current_web_browser.RegisterJsObject("callbackObj", current_helper);
    var cur_dir = Directory.GetCurrentDirectory();
    var url = $"file://{cur_dir}/ckeditor/editor.html";
    current_web_browser.Address = url;
    current_web_browser.RequestContext = new RequestContext();
    current_web_browser.RequestContext.SetPreference("browser.enable_spellchecking", true, out _);
    current_web_browser.RequestContext.SetPreference("spellcheck.dictionaries", new List<string> { "en-US" }, out _);
    grid.Children.Add(current_web_browser);
}

另一种方法用于使用户以后可以更改语言:

public void SetSpellcheck(Spellcheck language)
{
    if (language == Spellcheck.None) return;
    current_web_browser.RequestContext.SetPreference("spellcheck.dictionaries", new List<string> { get_locale_for_language(language) }, out _);
}

如您所见,我尝试设置拼写检查设置,但无论我在那里设置什么,都没有效果。我可以将 enable_spellcheck 设置为 false,它仍然会检查拼写,我设置的词典也会被忽略。将使用先前在 Locale 中设置的语言,而不是我放入词典的语言。 (我检查了 out 变量但没有错误) 我也尝试使用全局 RequestContext 但没有成功。

显然其他人以某种方式让它工作所以我觉得我在这里错过了一些重要的事情,或者做了一些完全愚蠢的事情。

另一件事是,如果我使用 GetAllPreferences(true),要获得所有默认设置的列表,我只会得到 null.

感谢@amaitlands 的评论,我现在知道问题是我在错误的线程中设置首选项。我误以为 CefSharp 在我的应用程序 UI-Thread 中 运行ning,而实际上它本身是 运行ning。

解决办法是用Cef.UIThreadTaskFactory.StartNew()到运行CefSharp里面的代码UI-Thread

Cef.UIThreadTaskFactory.StartNew(delegate
{
    current_web_browser.RequestContext.SetPreference("browser.enable_spellchecking", true, out _);
    current_web_browser.RequestContext.SetPreference("spellcheck.dictionaries", new List<object> { "en-US" }, out _);
});

我还必须将 List<> 的类型更改为 object,因为我使用的是 CefSharp.WPF 的旧版本,否则我会得到 Trying to set a preference of type LIST to value of type NULL错误。