Помогите найти самый глубокий дочерний элемент для проверки орфографии - PullRequest
1 голос
/ 01 октября 2009

Я пытаюсь изменить этот код, поскольку он повторяется ad nauseum во всей моей программе.

Моя проблема связана с тем, что на любой странице ( tabpage, panel, 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;
    }

Ответы [ 3 ]

3 голосов
/ 01 октября 2009

Я бы выбрал немного другой подход. Я бы создал интерфейс, скажем, 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);
            }
        }
2 голосов
/ 01 октября 2009

вы можете создать функцию, которая будет 'SpellCheck' для элемента управления и каждого из его дочерних элементов рекурсивно ...

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 children, form1 children & form1 (что, конечно, не MemoExEdit, поэтому проверяться не будет).

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

и он будет применять SpellCheck к детям формы 1 на любом уровне, если он будет углубляться.

0 голосов
/ 01 октября 2009

Вам необходимо использовать рекурсию для проверки иерархий элементов управления - самое простое, что нужно сделать, это проверить каждый элемент управления под данным корневым элементом управления:

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