好吧,最後我已經找到了解決方案的問題。如果您深入瞭解WPF源代碼,可以很容易地看到問題:有一個名爲TextEditorTyping
的內部類,它有一個名爲DoTextInput
的方法,該方法負責插入用戶輸入字符。此方法通過在TextEditor
(TextEditor
是另一個爲各種控件(例如RichTextBox
)提供文本編輯服務的內部類)調用SetSelectedText
來設置插入範圍的文化屬性。這裏是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;
}
所以方法是使用對應於Windows中的當前輸入語言的InputLanguageManager.Current.CurrentInputLanguage
。如果使用與英語不同的輸入語言(這是FrameworkElement.LanguageProperty的默認值),那麼如果編輯RichTextBox中的文本,FlowDocument中的插入元素將使用當前輸入語言作爲其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
事件解僱我們可以通過重寫的RichTextBox
的OnTextChanged
方法處理:
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>
它將神奇的工作。 :)
它對我來說工作得很好。 – Paparazzi
你能給我一些關於你測試什麼環境的暗示嗎?操作系統版本,.NET框架版本等... – Zsolt
這不是一個有效的FlowDocument併爲我引發語法錯誤。第一級元素必須從Block開始運行並且不運行。嘗試一個有效的第一級元素,如段落。 – Paparazzi