2009-10-01 1 views
1

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

Моя проблема связана с тем, что на любой странице (TabPage, панель, УНЦ и т.д.) есть элементы управления на различных уровнях для проверки орфографии.
т.е. ->

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

ответ

2

вы можете создать функцию, которая будет «проверка правописания» для контроля и каждый из своих детей recursivly ...

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 детских детей, Form1 детей & form1 (который, конечно, не MemoExEdit, так что не будет проверяться).

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

и он будет применять SpellCheck форму Form1 детей на любом уровне до тех пор, как он может пойти глубже.

+0

Это будет работать до тех пор, пока мне не нужно идти больше двух уровней, правильно? Если я закрою 'foreach loop' в' if (control.HasChildren()), то это будет более эффективно ???? Нет? –

+0

это будет работать на любом уровне, который вы хотите (на самом деле, пока есть «дети», эта функция будет идти на один шаг вниз, чтобы проверить заклинание их и их детей и т. Д.). Добавление if (control.HasChildren()) лучше. Я также добавлю уровень глубины, чтобы остановить функцию. – manji

3

Я бы выбрал несколько иной подход. Я бы создал интерфейс, скажем, ISpellCheckable, который имеет один метод SpellCheck.

Затем я бы расширил элемент управления TextBox, чтобы создать новый SpellCheckedTextBox, который реализует ISpellCheckable.

Затем замените соответствующие текстовые поля на вашей странице SpellCheckedTextBox (простое изменение).

Тогда вы могли бы просто написать единственный метод, который рекурсивно нисходит через все элементы управления на странице, проверять ли не осуществлять их ISpellCheckable, и если да, вызвав метод проверки правописания, например:

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

Спасибо за другой способ смотреть на это. Я все еще довольно зеленый и пока еще не реализовал свой собственный интерфейс. Ваш пример действительно имеет смысл для меня. –

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