C# Texbox 拼写检查器检查所有大写单词 [英] C# Texbox Spell Checker Check All Caps Words

查看:33
本文介绍了C# Texbox 拼写检查器检查所有大写单词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 WPF 中的文本框拼写检查,它似乎不会检查大写单词的拼写.我知道这是为首字母缩略词等而设计的,因此它不会将所有这些都标记为拼写错误,并且对此很有用.然而,在我的行业(建筑和工程)中,有许多公司使用所有大写字母来写他们的笔记,因此基本上使拼写检查无用......

With the textbox spell check in WPF, it doesn't seem to check spelling for words that are capitalized. I understand that this is designed for acronyms and such so that it doesn't tag all those as misspellings and it's useful for that. However in my industry (Architecture and Engineering) there are many companies that write their notes using all capitals so that basically makes the spell checking useless...

有什么办法可以让拼写检查器不忽略大写单词吗?

Is there any way to change the spell checker to not ignore capitalized words?

推荐答案

好的,所以我终于有时间再次尝试解决这个问题,并根据 Tom 的回答提出了一种方法(尽管这样做并不那么简单).我会警告你这绝对是一个黑客......但对于其他人来说,它似乎有效.基本上逻辑是这样的:

Ok so I finally got time to take another stab at this and came up with a way based on Tom's answer (though it's not as simple as doing that). I will warn you it is definitely a hack... But for anyone else struggling with this it seems to work. Essentially the logic goes like this:

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

我有点担心性能,但我的应用程序中有很多文本框,并且在使用它时我没有注意到任何减速.代码如下:

I was a little worried about performance but I have quite a few textboxes in my application and I have not noticed any slowdown while using this. Here is the code:

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

In the textbox loaded handler:

            //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;

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

Size and Text change handlers simply call the update method that looks like this:

        //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; }
        }

这是我创建的装饰器类的代码(它只是用红色下划线):

Here is the code for the adorner class I created (it just underlines in red):

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);
    }
}

当然,如果您使用右键单击来获取建议,您必须修改它以从阴影文本框而不是常规文本框中获取建议.

Then of course if you are using right click to get suggestions you have to modify that to get the suggestions from the shadow textbox instead of the regular one.

我发现的唯一怪癖是,因为它总是检查小写字母,所以它标识了诸如 Ive 和 Ill 之类的东西,因为 I 应该大写.我相信也有办法解决这个问题,但我还没有尝试过.

The only quirk I have found is that since it is always checking the lower case it identifies things like I've and I'll as misspellings since the I should be capitalized. I'm sure there is a way around that too but I haven't tried yet.

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

Anyway it's not pretty for sure but it seems to work and I can't find anything better without fully creating a new spell checking system altogether... I'm still open to other suggestions if anyone has them but this is at least workable.

意识到我实际上可以通过告诉它在调度程序上使用BeginInvoke"进行更新以异步运行它来进一步降低性能损失.现在文本更改和大小更改方法如下所示:

Realized I could actually further reduce performance hits by telling it to update with a 'BeginInvoke' on the dispatcher to run it async. Now the text changed and size changed methods look like this:

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

这篇关于C# Texbox 拼写检查器检查所有大写单词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆