4
votes

I've found numerous sites that provide examples of how to add a custom spellchecking dictionary to an individual textbox like so:

<TextBox SpellCheck.IsEnabled="True" >
    <SpellCheck.CustomDictionaries>
        <sys:Uri>customdictionary.lex</sys:Uri>
    </SpellCheck.CustomDictionaries>
</TextBox>

And I've tested this in my app and it works just fine.

However, I have industry specific jargon that I need to have ignored across ALL the textboxes in the application and applying this custom dictionary to each one individually seems to spit in the face of styles. At the moment I have a global textbox style to turn on spellchecking:

<Style TargetType="{x:Type TextBox}">
        <Setter Property="SpellCheck.IsEnabled" Value="True" />
</Style>

I tried to do something like this to add the custom dictionary, but it doesn't like it, since the SpellCheck.CustomDictionaries is read only and setters only take writable properties.

<Style TargetType="{x:Type TextBox}">
        <Setter Property="SpellCheck.IsEnabled" Value="True" />
        <Setter Property="SpellCheck.CustomDictionaries">
            <Setter.Value>
                <sys:Uri>CustomSpellCheckDictionary.lex</sys:Uri>
            </Setter.Value>
        </Setter>
</Style>

I have done extensive searches looking for the answer to this, but all examples show only the one-use scenario in the specific textbox as cited in the first code block. Any help is appreciated.

1

1 Answers

2
votes

I had the same issue and couldn't solve it with a style but created some code that accomplished the job.

First, I created a method to find all the textboxes contained within the visual tree of a parent control.

private static void FindAllChildren<T>(DependencyObject parent, ref List<T> list) where T : DependencyObject
{
    //Initialize list if necessary
    if (list == null)
        list = new List<T>();

    T foundChild = null;
    int children = VisualTreeHelper.GetChildrenCount(parent);

    //Loop through all children in the visual tree of the parent and look for matches
    for (int i = 0; i < children; i++)
    {
        var child = VisualTreeHelper.GetChild(parent, i);
        foundChild = child as T;

        //If a match is found add it to the list
        if (foundChild != null)
            list.Add(foundChild);

        //If this control also has children then search it's children too
        if (VisualTreeHelper.GetChildrenCount(child) > 0)
            FindAllChildren<T>(child, ref list);
    }
}

Then, anytime I open a new tab/window in my application I add a handler to the loaded event.

window.Loaded += (object sender, RoutedEventArgs e) =>
     {
         List<TextBox> textBoxes = ControlHelper.FindAllChildren<TextBox>((Control)window.Content);
         foreach (TextBox tb in textBoxes)
              if (tb.SpellCheck.IsEnabled)
                  Uri uri = new Uri("pack://application:,,,/MyCustom.lex"));
                       if (!tb.SpellCheck.CustomDictionaries.Contains(uri))
                           tb.SpellCheck.CustomDictionaries.Add(uri);
     };