C#Texbox拼写检查器检查所有上限词

时间:2016-05-18 19:36:01

标签: c# wpf textbox spell-checking

使用WPF中的文本框拼写检查,它似乎不会检查大写单词的拼写。我知道这是专为缩略词而设计的,所以它并没有将所有这些标记为拼写错误,而且对它有用。然而,在我的行业(架构和工程)中,有许多公司使用所有大写字母写下他们的笔记,这样基本上使得拼写检查无用......

有没有办法改变拼写检查器,不要忽略大写单词?

2 个答案:

答案 0 :(得分:1)

在通过拼写检查器运行之前,您可以简单地toLowerCase()字符串。

答案 1 :(得分:0)

好的,所以我终于抽出时间对此进行了另一次尝试,并提出了一种基于汤姆答案的方法(虽然这并不像那样简单)。我会警告你,这肯定是一个黑客......但对于其他任何挣扎于此的人来说似乎都有效。基本上逻辑是这样的:

  • 创建一个永不显示的“shadow”文本框,并将其文本设置为主文本框的小写版本并启用拼写检查。
  • 在影子文本框中搜索基于代码的拼写错误,并获取框中任何拼写错误的起始位置和长度。
  • 找到找到主文本框的字符索引的相对位置。
  • 使用装饰图层以红色为任何拼写错误的单词加下划线。
  • 更新文本并在文本更改或框大小更改时重新运行上述文本。

我有点担心性能,但我的应用程序中有很多文本框,我没有注意到使用它时有任何减速。这是代码:

在文本框中加载处理程序:

            //Create a shadow textbox to run spell check in - set text to the lower version of main text 
            TextBox tbSpell = new TextBox();
            tbSpell.Text = tb.Text.ToLower();

            //Enable spelling on the shadow box if we have spell checking enabled
            tbSpell.SpellCheck.IsEnabled = tb.DataContext is KeynoteVM && (tb.DataContext as KeynoteVM).EnableSpelling;

            //Set the shadow as a tag to the main textbox so we have access to it directly
            tb.Tag = tbSpell;

            //Adde handlers for size change or text change as we may need to update adorners
            tb.SizeChanged += tb_SizeChanged;
            tb.TextChanged += tb_TextChanged;

大小和文本更改处理程序只需调用如下所示的更新方法:

        //Remove existing adorners
        AdornerLayer lyr = AdornerLayer.GetAdornerLayer(tb);
        if (lyr != null)
        {
            Adorner[] ads = lyr.GetAdorners(tb);
            if (ads != null)
            {
                foreach (Adorner ad in lyr.GetAdorners(tb))
                { lyr.Remove(ad); }
            }
        }

        //Get the shadow textbox from the tag property
        TextBox tbSpell = tb.Tag as TextBox;
        if (tbSpell == null || !tbSpell.SpellCheck.IsEnabled)
        { return; }

        //Make sure we have the latest text
        tbSpell.Text = tb.Text.ToLower();

        //Loop to get all spelling errors starting at index 0
        int indx = 0;
        while (true)
        {
            //Find the spelling error
            indx = tbSpell.GetNextSpellingErrorCharacterIndex(indx, LogicalDirection.Forward);
            if (indx > -1)
            {
                //Have a match, get the length of the error word
                int len = tbSpell.GetSpellingErrorLength(indx);

                //Get a rectangle describing the position of the error to use for drawing the underline
                Rect r = tb.GetRectFromCharacterIndex(indx);
                Rect rEnd = tb.GetRectFromCharacterIndex(indx + len);

                //Modify the rectangle width to the width of the word
                r.Width = rEnd.Right - r.Right;

                //Create an adorner for the word and set the 'draw location' property to the rectangle
                AdornerSpell ad = new AdornerSpell(tb);
                ad.drawLocation = r;

                //Add the adorner to the textbox
                AdornerLayer.GetAdornerLayer(tb).Add(ad);

                //Increment the index to move past this word
                indx += len;
            }
            else
            { break; }
        }

以下是我创建的adorner类的代码(它只是用红色下划线):

public class AdornerSpell : Adorner
{
    public Rect drawLocation { get; set; }
    public AdornerSpell(UIElement adornedElement) : base(adornedElement) { }

    protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
    {
        drawingContext.DrawLine(new System.Windows.Media.Pen(new SolidColorBrush(Colors.Red), 1), drawLocation.BottomLeft, drawLocation.BottomRight);
    }
}

当然,如果您使用右键单击获取建议,则必须对其进行修改以从阴影文本框而不是常规文本框中获取建议。

我发现的唯一的怪癖是,因为它总是检查小写字母,它识别出像我一样的东西,我将作为拼写错误,因为我应该大写。我确信这方面也有办法,但我还没有尝试过。

无论如何它肯定不是很好但是它看起来很有效但如果没有完全创建一个新的拼写检查系统我找不到任何更好的东西...如果有人有它们我仍然愿意接受其他建议但这是在最不可行的。

修改

实现我实际上可以通过告诉它使用调度程序上的'BeginInvoke'进行更新以使其运行异步来进一步降低性能命中率。现在文本已更改,大小更改的方法如下所示:

Dispatcher.BeginInvoke(new Action(() => UpdateSpellingAdorners(sender as TextBox)));