首页 文章

拼写检查不适用于WPF RichTextBox

提问于
浏览
3

我正在尝试在WPF RichTextBox中启用拼写检查 . MSDN写道System.Windows.Controls.SpellCheck可用于启用TextBox和RichTextBox控件的拼写检查 .

不幸的是,以下代码对我不起作用:

<RichTextBox SpellCheck.IsEnabled="True" xml:lang="en-US"></RichTextBox>

这很奇怪,因为如果我使用普通的TextBox,它的工作原理非常好(如果我错过拼写的话,我可以看到红线) .

不幸的是,every answer我在SO上发现到目前为止只提到将 SpellCheck.IsEnabled 设置为 True 并将 Language 属性设置为支持的语言之一,但是我不知道为什么这个方法在我的计算机上不起作用在RichTextBoxes?

Update:

如果我这样写,运行中的文本将加下划线:

<RichTextBox SpellCheck.IsEnabled="True">
    <FlowDocument Language="en">
         <Paragraph>
             <Run>asdfasdf</Run>
         </Paragraph>
    </FlowDocument>
</RichTextBox>

但不幸的是,如果我尝试输入其他文本,它将被忽略 . 看起来属性 Language 未在编辑的内容上设置为英语 . 我试图设置甚至 Thread's CurrentCultureCurrentUICulture 没有结果......

1 回答

  • 5

    好的,最后我找到了问题的解决方案 . 如果你深入研究WPF源代码,可以很容易地看出这个问题:有一个名为 TextEditorTyping 的内部类,它有一个名为 DoTextInput 的方法,它负责插入用户输入字符 . 此方法通过在 TextEditor 上调用 SetSelectedText 来设置插入范围的culture属性( TextEditor 是另一个内部类,为各种控件提供文本编辑服务,例如 RichTextBox ) . 这是 DoTextInput 方法的一部分:

    IDisposable disposable = This.Selection.DeclareChangeBlock();
    using (disposable)
    {
        ITextSelection selection = This.Selection;
        if (!This.AllowOvertype || !This._OvertypeMode)
        {
             flag = false;
        }
        else
        {
             flag = str != "\t";
        }
        ((ITextRange)selection).ApplyTypingHeuristics(flag);
        // SETTING THE CULTURE ->
        This.SetSelectedText(str, InputLanguageManager.Current.CurrentInputLanguage);
        ITextPointer textPointer = This.Selection.End.CreatePointer(LogicalDirection.Backward);
        This.Selection.SetCaretToPosition(textPointer, LogicalDirection.Backward, true, true);
        undoCloseAction = UndoCloseAction.Commit;
    }
    

    因此该方法使用的 InputLanguageManager.Current.CurrentInputLanguage 对应于Windows中的当前输入语言 . 如果使用的输入语言不同于英语(这是FrameworkElement.LanguageProperty的默认值),那么如果编辑RichTextBox中的文本,FlowDocument中的inserted元素将使用当前输入语言作为其 Language 属性 . 例如,如果您的输入语言是匈牙利语( hu-hu ),您的FlowDocument将如下所示:

    <FlowDocument>
         <Paragraph>
             <Run xml:lang="hu-hu">asdfasdf</Run>
         </Paragraph>
    </FlowDocument>
    

    This site描述了同样的问题 .

    幸运的是,有一个解决方法 . 我们已经看到了 DoTextInput 方法的来源,里面有一个使用块:

    IDisposable disposable = This.Selection.DeclareChangeBlock();
    using (disposable)
    {
        ...
        // SETTING THE CULTURE ->
        This.SetSelectedText(str, InputLanguageManager.Current.CurrentInputLanguage);
        ...
    }
    

    这是一个更改块,它被放置在最后一行 - 在它被释放后, TextContainerChanged 事件被触发,我们可以通过覆盖 RichTextBoxOnTextChanged 方法来处理:

    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        var changeList = e.Changes.ToList();
        if (changeList.Count > 0)
        {
            foreach (var change in changeList)
            {
                TextPointer start = null;
                TextPointer end = null;
                if (change.AddedLength > 0)
                {
                    start = this.Document.ContentStart.GetPositionAtOffset(change.Offset);
                    end = this.Document.ContentStart.GetPositionAtOffset(change.Offset + change.AddedLength);
                }
                else
                {
                    int startOffset = Math.Max(change.Offset - change.RemovedLength, 0);
                    start = this.Document.ContentStart.GetPositionAtOffset(startOffset);
                    end = this.Document.ContentStart.GetPositionAtOffset(change.Offset);
                }
    
                if (start != null && end != null)
                {
                    var range = new TextRange(start, end);
                    range.ApplyPropertyValue(FrameworkElement.LanguageProperty, Document.Language);
                }
            }
        }
        base.OnTextChanged(e);
    }
    

    在这里,我们将编辑范围的语言重置为正确的值 - 到 Document.Language . 解决方法之后,您可以使用WPF拼写检查 - 例如,使用法语:

    <My:CultureIndependentRichTextBox xml:lang="fr-FR" SpellCheck.IsEnabled="True">
         <FlowDocument>
         </FlowDocument>
    </My:CultureIndependentRichTextBox>
    

    它会神奇地起作用 . :)

相关问题