Search code examples
c#wpfrichtextboxspell-checkingcultureinfo

How to apply cultureinfo (language) property to WPF richtextbox selection


I usually can find solutions somewhere on the web, and mostly here at SO. I have tried for two days now to resolve this issue with all attempts yielding the very same results. Hopefully someone here can provide the help I need.

I have not added any code for languages anywhere in the app except in the combobox where users can select the language and the dropdown event when they select the language seen below following the definition of the rtb.

below is the xaml definition of the richtextbox

            <RichTextBox Name="rtbDoc" IsDocumentEnabled="true" Padding="4"
                     MinHeight="350" HorizontalAlignment="Stretch"
                     VerticalAlignment="Stretch" SpellCheck.IsEnabled="True" VerticalScrollBarVisibility="Auto"
                     HorizontalScrollBarVisibility="Auto" AcceptsTab="True" IsTabStop="False"  
                     IsVisibleChanged="rtbDoc_IsVisibleChanged" 
                     KeyUp="rtbDoc_KeyUp" PreviewMouseUp="rtbDoc_MouseUp" PreviewMouseDown="rtbDoc_PreviewMouseDown"
                     PreviewKeyDown="rtbDocPreviewKeyDown"
                     ContextMenuOpening="rtb_ContextMenuOpening" 
                     ToolTip="Edit documents" Width="941"  >

Below is the code in the event where the language should be applied, but only changes the spellchecker, not only for the selected text but for the entire document.

               private void cbbLanguage_DropDownClosed(object sender, EventArgs e)
    {
        if (this.cbbLanguage.SelectedIndex < 0) { return; }

        int iLcid = (int)this.cbbLanguage.SelectedValue;
        _ci = new System.Globalization.CultureInfo(iLcid);

        // following does not seem to have any desire affect
        //System.Threading.Thread.CurrentThread.CurrentCulture = _ci;
        //System.Threading.Thread.CurrentThread.CurrentUICulture = _ci;
        //CultureInfo ci2 = CultureInfo.CreateSpecificCulture(_ci.Name);

        // both of following changes only spellchecker for document so that all English text underlined
        //InputLanguageManager.SetInputLanguage(this.rtbDoc, CultureInfo.CreateSpecificCulture(ci2.Name));
        //XmlLanguage xl = this.rtbDoc.Document.Language;

        int iIdx = this.cbbLanguage.SelectedIndex;
        DataRowView drv = this.cbbLanguage.SelectedItem as DataRowView;
        DataRow[] dr = _dtLanguages.Select("LanguageId = " + drv[0].ToString());  // number id of language selected

        XmlLanguage xl2 = XmlLanguage.GetLanguage(dr[0]["LanguageName"].ToString());

        // this works in changing the property and all words in document 
        //  become underlined indicating spellchecker changed but text remained English
        //this.rtbDoc.Language = xl2;  

        if (this.rtbDoc.Selection.Text.Length > 1)
        {
            // this works to immediately (no focus change necessary) to 
            //   change the property and the spellchecker shows the entire 
            //   doc content misspelled, but the selected text remains english
            this.rtbDoc.Selection.ApplyPropertyValue(FrameworkElement.LanguageProperty, xl2);  
        }

    }

Solution

  • You can do with the GotFocus and LostFocus events from rtbDoc and changing the InputLanguageManager.

    <RichTextBox Name="rtbDoc" IsDocumentEnabled="true" Padding="4"
                     GotFocus="ChangeLanguage"
                     LostFocus="ChangeToDefault"
                     MinHeight="350" HorizontalAlignment="Stretch"
                     VerticalAlignment="Stretch" SpellCheck.IsEnabled="True" VerticalScrollBarVisibility="Auto"
                     HorizontalScrollBarVisibility="Auto" AcceptsTab="True" IsTabStop="False"  
                     IsVisibleChanged="rtbDoc_IsVisibleChanged" 
                     KeyUp="rtbDoc_KeyUp" PreviewMouseUp="rtbDoc_MouseUp" PreviewMouseDown="rtbDoc_PreviewMouseDown"
                     PreviewKeyDown="rtbDocPreviewKeyDown"
                     ContextMenuOpening="rtb_ContextMenuOpening" 
                     ToolTip="Edit documents" Width="941"  >
    

    and in code

    public CultureInfo defaultLanguage;
    public CultureInfo ci;
    private void cbbLanguage_DropDownClosed(object sender, EventArgs e)
    {
    
        int iLcid = Int32.Parse(_lstLanguages[this.cbbLanguage.SelectedIndex].LanguageId);
        ci = new System.Globalization.CultureInfo(iLcid);
        System.Threading.Thread.CurrentThread.CurrentCulture = ci;
        System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
        CultureInfo ci2 = CultureInfo.CreateSpecificCulture(ci.Name);
    
        //InputLanguageManager.SetInputLanguage(this.rtbDoc, CultureInfo.CreateSpecificCulture(ci2.Name));
        XmlLanguage xl = this.rtbDoc.Document.Language;
        XmlLanguage xl2 = XmlLanguage.GetLanguage(ci2.IetfLanguageTag);
    
        // this works in changing the property but nothing changes in the doc
        this.rtbDoc.Language = xl2;  
    
        if (this.rtbDoc.Selection.Text.Length > 1)
        {
            // this works to change the property and the spellchecker shows the entire 
            // doc content misspelled, but the selected text remains english
            this.rtbDoc.Selection.ApplyPropertyValue(FrameworkElement.LanguageProperty, xl2);  
        }
    
    }
    
    private void ChangeLanguage(object sender, RoutedEventArgs e)
        {
            defaultLanguage = InputLanguageManager.Current.CurrentInputLanguage;
            InputLanguageManager.Current.CurrentInputLanguage = CultureInfo.CreateSpecificCulture(ci.Name);
    
        }
    
    private void ChangeToDefault(object sender, RoutedEventArgs e)
        {
            InputLanguageManager.Current.CurrentInputLanguage = defaultLanguage;