Developing ClickOnce WPF application, it was needed to implement a spell checker for the different text boxes of the application. Our development environment was Windows 7, and using the .NET Framework 4 both the framework and the OS in english. The problem appeared when we tested the application, where the spell check in french or other non-english languages was not working at all. After several readings on the web and other experimentations using a quick-and-dirty application, I would like to give my findings here.
Basically, the XAML of my testing application is the one below :
<Window x:Class=”TestApplication.MainWindow”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
Title=”MainWindow” Height=”350″ Width=”525″>
<Grid>
<RichTextBox Margin=”0,52,0,65″ Name=”rtbText” SpellCheck.IsEnabled=”True” Language=”fr”>
<FlowDocument>
<Paragraph>
The quick brown fox jumps over the lazy dog
Le renard brun rapide saute sur le chien paresseux
Die schnelle braune Fuchs springt ??ber den faulen Hund
</Paragraph>
</FlowDocument>
</RichTextBox>
<Button Content=”FR” Height=”23″ HorizontalAlignment=”Left” Name=”btnFR” VerticalAlignment=”Top” Width=”30″ Click=”btnFR_Click” />
<Button Content=”EN” Height=”23″ HorizontalAlignment=”Left” Margin=”36,0,0,0″ Name=”btnEN” VerticalAlignment=”Top” Width=”30″ Click=”btnEN_Click” />
<Button Content=”Save” Height=”23″ HorizontalAlignment=”Left” Margin=”428,0,0,0″ Name=”btnSave” VerticalAlignment=”Top” Width=”75″ Click=”btnSave_Click” />
<RichTextBox Language=”fr” Margin=”0,264,97,0″ Name=”rtbSwitch” SpellCheck.IsEnabled=”True”>
</RichTextBox>
<Button Content=”DE” Height=”23″ HorizontalAlignment=”Left” Margin=”72,0,0,0″ Name=”btnDE” VerticalAlignment=”Top” Width=”30″ Click=”btnDE_Click” />
</Grid>
</Window>
Which gives the window below :
When one of the upper-left button is clicked, a code similar to the one below is executed :
private void btnEN_Click(object sender, RoutedEventArgs e)
{
TextRange tr = new TextRange(rtbText.Document.ContentStart, rtbText.Document.ContentEnd);
tr.ApplyPropertyValue(FlowDocument.LanguageProperty, “en”);
}
Basically, it takes the whole content of the Rich Text Box and change the “Language??? property to the language in which the spell check has to be done.
Now, the problem is that if you compile the application on the .NET Framework 4, it will not work……..unless the corresponding language packs of the Framework. They are all available on the Microsoft Download Center. Indeed, according to the table below, as soon as you use the .NET Framework 4, the language packs have to be installed, whereas if you use the .NET Framework 3.5 SP1, it depends on the platform on which the application is running. On Windows Vista and Windows 7, no need to install the language packs, for Windows XP, they are needed :
Windows XP | Windows Vista | Windows 7 | |
.NET 3.5 SP1 | Language Packs Needed | No need for the Language Packs | No need for the Language Packs |
.NET 4 | Language Packs Needed | Language Packs Needed | Language Packs Needed |
So, reverting back to the .NET Framework 3.5 made the spell checking to work.
That would be it, but, when typing new text, the spell check was not working and the reason can be found in the XAML extract of the Rich Text Box (“Save??? button). When switching to english, I supposed that the new text would be checked against the english language, which is completely wrong. The XAML below shows the text right after the switch to the english language :
<Section xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xml:space=”preserve” TextAlignment=”Left” LineHeight=”Auto” IsHyphenationEnabled=”False” xml:lang=”fr” FlowDirection=”LeftToRight” NumberSubstitution.CultureSource=”Text” NumberSubstitution.Substitution=”AsCulture” FontFamily=”Segoe UI” FontStyle=”Normal” FontWeight=”Normal” FontStretch=”Normal” FontSize=”12″ Foreground=”#FF000000″ Typography.StandardLigatures=”True” Typography.ContextualLigatures=”True” Typography.DiscretionaryLigatures=”False” Typography.HistoricalLigatures=”False” Typography.AnnotationAlternates=”0″ Typography.ContextualAlternates=”True” Typography.HistoricalForms=”False” Typography.Kerning=”True” Typography.CapitalSpacing=”False” Typography.CaseSensitiveForms=”False” Typography.StylisticSet1=”False” Typography.StylisticSet2=”False” Typography.StylisticSet3=”False” Typography.StylisticSet4=”False” Typography.StylisticSet5=”False” Typography.StylisticSet6=”False” Typography.StylisticSet7=”False” Typography.StylisticSet8=”False” Typography.StylisticSet9=”False” Typography.StylisticSet10=”False” Typography.StylisticSet11=”False” Typography.StylisticSet12=”False” Typography.StylisticSet13=”False” Typography.StylisticSet14=”False” Typography.StylisticSet15=”False” Typography.StylisticSet16=”False” Typography.StylisticSet17=”False” Typography.StylisticSet18=”False” Typography.StylisticSet19=”False” Typography.StylisticSet20=”False” Typography.Fraction=”Normal” Typography.SlashedZero=”False” Typography.MathematicalGreek=”False” Typography.EastAsianExpertForms=”False” Typography.Variants=”Normal” Typography.Capitals=”Normal” Typography.NumeralStyle=”Normal” Typography.NumeralAlignment=”Normal” Typography.EastAsianWidths=”Normal” Typography.EastAsianLanguage=”Normal” Typography.StandardSwashes=”0″ Typography.ContextualSwashes=”0″ Typography.StylisticAlternates=”0″><Paragraph><Run xml:lang=”en”>The quick brown fox jumps over the lazy dog Le renard brun rapide saute sur le chien paresseux Die schnelle braune Fuchs springt ??ber den faulen Hund</Run></Paragraph></Section>
The interesting part is the last <Run> element, that contains an xml:lang=???en??? attribute, specifying that the enclosed text is in english. When some text is entered, the corresponding XAML becomes the following :
<Section xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xml:space=”preserve” TextAlignment=”Left” LineHeight=”Auto” IsHyphenationEnabled=”False” xml:lang=”fr” FlowDirection=”LeftToRight” NumberSubstitution.CultureSource=”Text” NumberSubstitution.Substitution=”AsCulture” FontFamily=”Segoe UI” FontStyle=”Normal” FontWeight=”Normal” FontStretch=”Normal” FontSize=”12″ Foreground=”#FF000000″ Typography.StandardLigatures=”True” Typography.ContextualLigatures=”True” Typography.DiscretionaryLigatures=”False” Typography.HistoricalLigatures=”False” Typography.AnnotationAlternates=”0″ Typography.ContextualAlternates=”True” Typography.HistoricalForms=”False” Typography.Kerning=”True” Typography.CapitalSpacing=”False” Typography.CaseSensitiveForms=”False” Typography.StylisticSet1=”False” Typography.StylisticSet2=”False” Typography.StylisticSet3=”False” Typography.StylisticSet4=”False” Typography.StylisticSet5=”False” Typography.StylisticSet6=”False” Typography.StylisticSet7=”False” Typography.StylisticSet8=”False” Typography.StylisticSet9=”False” Typography.StylisticSet10=”False” Typography.StylisticSet11=”False” Typography.StylisticSet12=”False” Typography.StylisticSet13=”False” Typography.StylisticSet14=”False” Typography.StylisticSet15=”False” Typography.StylisticSet16=”False” Typography.StylisticSet17=”False” Typography.StylisticSet18=”False” Typography.StylisticSet19=”False” Typography.StylisticSet20=”False” Typography.Fraction=”Normal” Typography.SlashedZero=”False” Typography.MathematicalGreek=”False” Typography.EastAsianExpertForms=”False” Typography.Variants=”Normal” Typography.Capitals=”Normal” Typography.NumeralStyle=”Normal” Typography.NumeralAlignment=”Normal” Typography.EastAsianWidths=”Normal” Typography.EastAsianLanguage=”Normal” Typography.StandardSwashes=”0″ Typography.ContextualSwashes=”0″ Typography.StylisticAlternates=”0″><Paragraph><Run xml:lang=”en”>The quick brown fox jumps over the lazy dog Le renard brun rapide saute sur le chien paresseux Die schnelle braune Fuchs springt ??ber den faulen Hund</Run><Run xml:lang=”fr-ch”> another text </Run></Paragraph></Section>
Surprisingly, the last <Run> element is now using the xml:lang=???fr-ch??? language. What happens ? It simply takes the input language of the keyboard. It also means that if you want to change the on-the-fly spell check, the input language has to be changed. As an example, the click event handler written above becomes :
private void btnEN_Click(object sender, RoutedEventArgs e)
{
TextRange tr = new TextRange(rtbText.Document.ContentStart, rtbText.Document.ContentEnd);
tr.ApplyPropertyValue(FlowDocument.LanguageProperty, “en”);
InputLanguageManager.Current.CurrentInputLanguage = new CultureInfo(“en-us”);
}
At the last line of the event handler, the keyboard input language is changed and you will notice it in the tray bar, if displaying the current input language, that the locale has changed. Very important, the culture has to absolutely match an input language installed in the regional settings.
Changing the input language is not the best way as it changes the layout of the keyboard (for example, switching to en-us a fr-ch keyboard layout will lose the accented characters) and so far I have not yet found a way to workaround this.
0 Comments