I'm using the built in spell checker in WPF. It was working just fine until I had users start upgrading to windows 10... I think the issue is that it's being used for a lot of small text boxes. My application presents a grid (Telerik's TreeListView) with text boxes for one of the columns which i want spell checked. I need to be able to provide a custom dictionary to the spell checker; the only way I was able to do this was to subscribe to the textbox loaded event and add the paths in as follows:
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); }
Granted this calls the add for each and every text box which seems terribly wasteful, but it seemed to be working just fine with little noticeable lag and only on load up. However now on Windows 10 it seems to be a ridiculous lag. On my Windows 8.1 machine I load up a file with a few thousand rows and it appears in about 3 or 4 seconds; on my Windows 10 box, it appears in about 10-15 minutes. If I comment out the custom dictionaries portion of the above code it's back to about 3-4 seconds on either machine.
Does anyone know a better way to do this? Or if there is some way around it in Win10?
Starting .NET 4.6.1 (in Win8.1 & Win10), WPF uses ISpellChecker interface exposed by the OS to implement its SpellChecker, and the performance characteristics could be somewhat different indeed.
Notably, ISpellChecker's custom dictionary registrar acts globally - it no longer acts as a per-control registration. (See KB article link below). As a result, registering the same set of dictionaries over and over for each control is wasteful and can potentially degrade your performance. Besides, the OS will just start ignoring your dictionaries when it reaches an internal limit.
Just register the dictionaries once, or use the alternative registration mechanism outlined at http://blogs.msdn.com/b/wpf/archive/2015/10/29/wpf-in-net-4-6-1.aspx and place the files under %appdata%\microsoft\spelling\.
If you need to run the same application on Win7/Win8 as well as Win8.1/Win10, you may need to detect the OS and branch your dictionary registration strategy.
In general, typical uses of custom dictionaries should continue working as usual - with little difference between .NET 4.6.1 vs previous releases.
Also see https://support.microsoft.com/en-us/kb/3088234 for additional information.
We have experienced a similar issue and saw improved performance by avoiding re-registering custom dictionaries on every TextBox control during load.
Unfortunately, we hit another issue with the way custom dictionaries are handled which can also result in very long loading times if you have even a small number of TextBox controls.
When a WPF application registers a custom dictionary in .NET 4.6.1 on Windows 8.1/10, a temporary dictionary file is created in %localappdata%\Temp and this is registered in the multistring value _GLOBAL_ in the registry key "Computer\HKEY_CURRENT_USER\Software\Microsoft\Spelling\Dictionaries".
If the _GLOBAL_ value ends up referencing a dictionary file which does not exist, the application starts to exhibit very slow loading whenever a control with spell check enabled is initialized.
This can happen by using the "Stop debugging" button in Visual Studio and then running the Disk Clean-up or CCleaner after enough time has passed for these to delete the temp dictionary files.
We managed to fix this by clearing the _GLOBAL_ value of any links to dictionary files which did not exist. The our application began to work as expected.
We raised the following connect bug:
https://connect.microsoft.com/VisualStudio/feedback/details/2153484