我在WPF中使用内置的拼写检查程序。它工作得很好,直到我让用户开始升级到Windows 10 ...我认为问题是它被用于许多小文本框。我的应用程序提供了一个网格(Telerik的TreeListView),其中包含我希望拼写检查的其中一列的文本框。我需要能够为拼写检查器提供自定义词典;我能够做到这一点的唯一方法是订阅加载文本框的事件并按如下方式添加路径:
TextBox tb = sender as TextBox;
tb.ContextMenu = ctx_Spell;
IList dcts = SpellCheck.GetCustomDictionaries(tb);
dictsList.Add(dcts);
if (KMApplication.Settings.UserDictionary != null)
{ dcts.Add(KMApplication.Settings.UserDictionary); }
foreach (Uri dct in KMApplication.Settings.RevitDictonaries)
{ dcts.Add(dct); }
当然,这会调用每个文本框的添加内容,这看起来非常浪费,但它似乎工作得很好,几乎没有明显的延迟,只有在加载时。但是现在在Windows 10上似乎是一个荒谬的滞后。在我的Windows 8.1机器上,我加载了几千行的文件,它出现在大约3或4秒内;在我的Windows 10盒子上,它出现在大约10-15分钟。如果我将上述代码的自定义词典部分注释掉,那么它在任何一台机器上都会恢复大约3-4秒。
有谁知道更好的方法吗?或者如果在Win10中有一些解决方法?
答案 0 :(得分:6)
我们遇到了类似的问题,并且在加载过程中避免在每个TextBox控件上重新注册自定义词典,从而提高了性能。
不幸的是,我们遇到了处理自定义词典的方式的另一个问题,如果你甚至有少量的TextBox控件,也会导致非常长的加载时间。
当WPF应用程序在Windows 8.1 / 10上的.NET 4.6.1中注册自定义词典时,会在%localappdata%\ Temp中创建一个临时词典文件,并在注册表项中的多字符串值_GLOBAL_中注册&# 34;计算机\ HKEY_CURRENT_USER \ SOFTWARE \微软\拼写\字典"
如果_GLOBAL_值最终引用不存在的字典文件,则只要初始化启用了拼写检查的控件,应用程序就会开始显示非常慢的加载。
这可以通过使用"停止调试"在Visual Studio中按钮,然后在经过足够的时间后运行磁盘清理或CCleaner,以删除临时字典文件。
我们设法通过清除任何不存在的字典文件链接的_GLOBAL_值来解决这个问题。我们的应用程序开始按预期工作。
我们提出了以下连接错误: https://connect.microsoft.com/VisualStudio/feedback/details/2153484
答案 1 :(得分:4)
启动.NET 4.6.1(在Win8.1& Win10中),WPF使用操作系统公开的ISpellChecker接口来实现其SpellChecker,性能特征确实有些不同。
值得注意的是,ISpellChecker的自定义词典注册商在全球范围内行事 - 它不再作为每个控件注册。 (参见下面的KB文章链接)。因此,为每个控件反复注册同一组字典是浪费的,并且可能会降低您的性能。此外,操作系统只会在达到内部限制时开始忽略您的词典。
只需注册字典一次,或使用http://blogs.msdn.com/b/wpf/archive/2015/10/29/wpf-in-net-4-6-1.aspx中列出的备用注册机制,并将文件放在%appdata%\ microsoft \ spelling \下。
如果您需要在Win7 / Win8以及Win8.1 / Win10上运行相同的应用程序,您可能需要检测操作系统并分支您的字典注册策略。
一般来说,自定义词典的典型用法应该像往常一样继续工作 - .NET 4.6.1与之前版本之间几乎没有区别。
答案 2 :(得分:0)
首先,我想提一提,我知道该帖子已经有几年历史了,但我认为我的回答可能会帮助那里有相同问题但提出的解决方案不起作用的人(像我一样)。
对我来说,解决的是将以下代码添加到 App.config :
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.Controls.DoNotAugmentWordBreakingUsingSpeller=true"/>
</runtime>
或者,您也可以在InitializeComponent()调用后插入以下代码:
AppContext.SetSwitch(@"Switch.System.Windows.Controls.DoNotAugmentWordBreakingUsingSpeller", true);