首页 文章

WPF richtextbox的冲突语言设置

提问于
浏览
11

在具有文化设置“de-DE”(或“en-US”以外的任何其他设备)的计算机上,我希望启用一个启用了拼写检查的RichTextBox,并将选中的语言设置为英语(“en-US”) .

<RichTextBox SpellCheck.IsEnabled="True" Language="en-US"/>

这会启用拼写检查,但会检查"de-DE" culture,而不是"en-US" . 添加 xml:lang="en-us" 时也是如此 .

然而,

<RichTextBox SpellCheck.IsEnabled="True" InputLanguageManager.InputLanguage="en-US"/>

正确启用英语拼写检查,但也将键盘布局更改为“en-US” .

如何使用系统的键盘设置(在我的情况下为“de-DE”),但RichTextBox的拼写检查是英语?

(可能相关:我正在使用.NET Framework 4.5)

1 回答

  • 4

    我试图重现你的问题,对我来说,除了英语之外,我无法使用其他语言激活拼写检查,尽管我在组件初始化之前更改了区域设置和线程文化:

    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("de-DE");
        Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("de-DE");
    

    根据提供的解决方案here,我能够使它工作:

    1) Inherit from RichTextBox:

    class RichTextBoxEx : RichTextBox
    {
        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);
        }
    }
    

    2) Use it in your xaml

    <local:RichTextBoxEx x:Name="richTextBox" HorizontalAlignment="Left" Height="100" Margin="33,100,0,0" VerticalAlignment="Top" Width="474" 
                 xml:lang="de-DE" SpellCheck.IsEnabled="True">
    

    [edit]

    我还试图避免为每个文本更改应用属性值,方法是定义计时器并不时拼写检查所有内容 . 在我的电脑上,使用the longest Wikipedia article content时我看不出区别:

    class RichTextBoxEx : RichTextBox
    {
        DispatcherTimer timer;
        bool textChanged = false;
    
        public RichTextBoxEx()
        {
            if (DesignerProperties.GetIsInDesignMode(this))
                return;
    
            timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 1);
            timer.Tick += timer_Tick;
            timer.Start();
        }
    
        void timer_Tick(object sender, EventArgs e)
        {
            try
            {
                var range = new TextRange(Document.ContentStart, Document.ContentEnd);
                range.ApplyPropertyValue(FrameworkElement.LanguageProperty, Document.Language);
            }
            finally
            {
                textChanged = false;
            }
        }
    
        protected override void OnTextChanged(TextChangedEventArgs e)
        {
            // TODO: remove if timer version works correctly
            //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);
            //        }
            //    }
            //}
    
            textChanged = true;
            base.OnTextChanged(e);
        }
    }
    

相关问题