1

我正在尝试重构此代码,因为它在我的程序 中反复出现,令人作呕。

我的问题与在任何给定页面(标签页、面板、uc 等)上都有多个级别的拼写检查控件有关。
即——>

            foreach (Control control in tpgSystems.Controls)
            {
                if (control.GetType() == typeof(MemoExEdit))
                {
                    if (control.Text != String.Empty)
                    {
                        control.BackColor = Color.FromArgb(180, 215, 195);
                        control.Text = HUD.Spelling.CheckSpelling(control.Text);
                        control.ResetBackColor();
                    }
                }
            }
            foreach (Control control in grpCogestiveHeartFailure.Controls)
            {
                if (control.GetType() == typeof(MemoExEdit))
                {
                    if (control.Text != String.Empty)
                    {
                        control.BackColor = Color.FromArgb(180, 215, 195);
                        control.Text = HUD.Spelling.CheckSpelling(control.Text);
                        control.ResetBackColor();
                    }
                }
            }
            foreach (Control control in grpDiabetes.Controls)
            {
                if (control.GetType() == typeof(MemoExEdit))
                {
                    if (control.Text != String.Empty)
                    {
                        control.BackColor = Color.FromArgb(180, 215, 195);
                        control.Text = HUD.Spelling.CheckSpelling(control.Text);
                        control.ResetBackColor();
                    }
                }
            }

正如您在示例中看到的那样,tpgSystems直接在上面有一些控件,然后有两个Group Boxes也有控件。

我的部分目标是仅检查可能需要拼写检查的控件,例如Text Boxes亲戚。

我知道有control.HasChildren()我可以使用的东西,但让我逃避的是如何使用它并告诉我要走多远。我会假设两个级别是我所经历的最深层次,但这似乎是短视的硬编码。

理想情况下,我会弄清楚如何将控件传递给我CheckSpelling(),然后在那里有逻辑来确定要走多远。可能使用反射

为了完整起见,CheckSpelling()这是在我创建的一个单独的库中。

public string CheckSpelling(string text)
    {
        Word.Application app = new Word.Application();
        object nullobj = Missing.Value;
        object template = Missing.Value;
        object newTemplate = Missing.Value;
        object documentType = Missing.Value;
        object visible = false;
        object optional = Missing.Value;
        object savechanges = false;
        app.ShowMe();

        Word._Document doc = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);

        doc.Words.First.InsertBefore(text);
        Word.ProofreadingErrors errors = doc.SpellingErrors;

        var ecount = errors.Count;
        doc.CheckSpelling(ref optional, ref optional, ref optional, ref optional, 
            ref optional, ref optional, ref optional, ref optional, ref optional, 
            ref optional, ref optional, ref optional);
        object first = 0;
        object last = doc.Characters.Count - 1;
        var results = doc.Range(ref first, ref last).Text;
        doc.Close(ref savechanges, ref nullobj, ref nullobj);
        app.Quit(ref savechanges, ref nullobj, ref nullobj);

        return results;
    }
4

3 回答 3

3

我会采取稍微不同的方法。我会创建一个接口,比如说 ISpellCheckable,它有一个名为 SpellCheck 的方法。

然后,我将扩展 TextBox 控件以创建一个新的 SpellCheckedTextBox,它实现了 ISpellCheckable。

然后,将页面上的相关文本框替换为 SpellCheckedTextBox(简单更改)。

然后,您可以简单地编写一个方法,递归地遍历页面上的所有控件,检查它们是否实现 ISpellCheckable,如果是,则调用 SpellCheck 方法,例如:

void WalkControls(Control root)
        {
            if (root == null ) return;
            foreach (Control control in root.Controls)
            {
                if (control is ISpellCheckable)
                {
                    if (((ISpellCheckable)control).SpellCheck())
                    {
                        // do stuff
                    }
                }
                WalkControls(control);
            }
        }
于 2009-10-01T13:38:46.570 回答
2

您可以创建一个函数,该函数将递归地为控件及其每个子项“拼写检查”...

public void SpellCheckControl(Control control, int depth)
{
    if(depth != 0)
    {
        if(Control.HasChildren())
        {
            foreach (Control ctrl in control.Controls)
            {
                SpellCheckControl(ctrl, depth - 1);
            }
        }
    }

    if (control.GetType() == typeof(MemoExEdit))
    {
        if (control.Text != String.Empty)
        {
            control.BackColor = Color.FromArgb(180, 215, 195);
            control.Text = HUD.Spelling.CheckSpelling(control.Text);
            control.ResetBackColor();
        }
    }
}

现在,您可以像这样使用此功能:

SpellCheckControl(form1, 2); //form1 is your main form for example

将 SpellCheck 应用于 form1 children's children、form1 children & form1(这当然不是 MemoExEdit,因此不会被检查)。

SpellCheckControl(form1, -1); //form1 is your main form for example

只要它可以更深入,它就会将 SpellCheck 应用于任何级别的 form1 子级。

于 2009-10-01T13:43:49.593 回答
0

您需要使用递归来检查控件层次结构 - 最简单的做法是检查给定根控件下的每个控件:

public void CheckSpellingRec(IEnumerable<Control> controls)
{
    foreach(var c in controls)
    {
        if(c is MemoExEdit && c.Text != String.Empty)
        {
            //check spelling
            control.BackColor = Color.FromArgb(180, 215, 195);
            control.Text = HUD.Spelling.CheckSpelling(control.Text);
            control.ResetBackColor();
        }

        //check spelling of child controls
        CheckSpellingRec(c.Controls.Cast<Control>());
    }
}

public void CheckSpelling(Control parent)
{
    CheckSpellingRec(new[] { parent });
}
于 2009-10-01T13:44:05.130 回答