Помогите с решением вопроса, буду очень благодарен за решение:
C#. Net 2.0
Имеется список, содержащий имена объектов на форме, например:
tbxOK — кнопка,
tbxCancel — кнопка,
toolstripItemDone — элемент MenuItem,
ToolBtnInfo — элемент ToolStrip.
Список этот динамически меняется и мне необходимо, пройдя по всем контролам формы, сделать Enable=false для элементов из списка.
При проходе нижеследующим образом код работает только в том случае, если все контролы из списка являются кнопками, списками, текстовыми полями, т.е. у них родитель — основная форма:
foreach (DataRow row in viewAllTableAdapter.GetData(tbxLogin.Text, this.Name.ToString()))
//Получаем список контролов в указанной форме для отключения
{
this.Controls[row[2].ToString()].Enabled = false;
}
В случае, если я имею контрол типа toolstripItemDone — верхнее меню, и в нем например, Вид — Выделить все, то, само собой, он не дизейблится, т.к. он находится в контейнере MenuStrip.
В случае обхода таким путем:
Все равно не проходит, т.к. форма ловит только MenuStrip, а его дочерние элементы не проходит.
Подскажите способ отключения/скрытия любого контрола независимо от его родителя? Способ:
this.Controls.Find("имя_контрола", true)[0].Enabled = false;
не работает, говорит что индекс вне диапазона.
Мне предложили вариант с предикатами:
public static bool ForEachInChildControlsTree(Control parent, Predicate action)
{
foreach (Control c in parent.Controls)
{
if (action(c))
return true;
if (ForEachInChildControlsTree(c, action))
return true;
}
return false;
}
............
ForEachInChildControlsTree(this /*форма или другой родитель*/, delegate(Control ctl)
{
ctl.Enabled = ;
return false;
});
Но я не могу разобраться, куда именно мне надо подставить имя из списка для отключения.
Если оставить код как приведен и вписать ctl.Enabled =false; то все элементы затеняются.
Если вместо this в параметре указать mytoolstrip, то ничего не происходит.
Подскажите, пожалуйста, в каком направлении копать?
Re: Скрытие различных элементов формы, указанных в списке
Здравствуйте, Mdel, Вы писали:
M>В случае, если я имею контрол типа toolstripItemDone — верхнее меню, и в нем например, Вид — Выделить все, то, само собой, он не дизейблится, т.к. он находится в контейнере MenuStrip.
ToolStripItem-ы — это не контролы. Соответственно их нет в дереве контролов формы.
M>Подскажите, пожалуйста, в каком направлении копать?
Обходить ToolStripItem-ы отдельным циклом.
Re: Скрытие различных элементов формы, указанных в списке
Здравствуйте, Mdel, Вы писали:
M>Помогите с решением вопроса, буду очень благодарен за решение: M>C#. Net 2.0 M>Имеется список, содержащий имена объектов на форме, например: M>tbxOK — кнопка, M>tbxCancel — кнопка, M>toolstripItemDone — элемент MenuItem, M>ToolBtnInfo — элемент ToolStrip. M>Список этот динамически меняется и мне необходимо, пройдя по всем контролам формы, сделать Enable=false для элементов из списка. M>При проходе нижеследующим образом код работает только в том случае, если все контролы из списка являются кнопками, списками, текстовыми полями, т.е. у них родитель — основная форма: M>foreach (DataRow row in viewAllTableAdapter.GetData(tbxLogin.Text, this.Name.ToString())) M>//Получаем список контролов в указанной форме для отключения M>{ M>this.Controls[row[2].ToString()].Enabled = false; M>} M>В случае, если я имею контрол типа toolstripItemDone — верхнее меню, и в нем например, Вид — Выделить все, то, само собой, он не дизейблится, т.к. он находится в контейнере MenuStrip. M>В случае обхода таким путем:
M>
M>Все равно не проходит, т.к. форма ловит только MenuStrip, а его дочерние элементы не проходит. M>Подскажите способ отключения/скрытия любого контрола независимо от его родителя? Способ: M>this.Controls.Find("имя_контрола", true)[0].Enabled = false; M>не работает, говорит что индекс вне диапазона. M>Мне предложили вариант с предикатами:
M>
M>public static bool ForEachInChildControlsTree(Control parent, Predicate action)
M>{
M> foreach (Control c in parent.Controls)
M> {
M> if (action(c))
M> return true;
M> if (ForEachInChildControlsTree(c, action))
M> return true;
M> }
M> return false;
M>}
M>
M>............
M>
M>ForEachInChildControlsTree(this /*форма или другой родитель*/, delegate(Control ctl)
M>{
M> ctl.Enabled = ;
M> return false;
M>});
M>
M>Но я не могу разобраться, куда именно мне надо подставить имя из списка для отключения. M>Если оставить код как приведен и вписать ctl.Enabled =false; то все элементы затеняются. M>Если вместо this в параметре указать mytoolstrip, то ничего не происходит. M>Подскажите, пожалуйста, в каком направлении копать?
Объяснять долго мне некогда, код понятный, помоему по поиску чего либо в любом контейнере
foreach (Control Cntrl in groupBoxПроверка.Controls)//ищем все чекеты на групповой панели проверки знаний
{
if (Cntrl is CheckBox)//if (((CheckBox)Cntrl).Checked) a += b;
{
ИмяЧекета = ((CheckBox)Cntrl).Name; ИДчекета = ИмяЧекета.Split ( '_' );
ID_Ответа = Convert.ToInt32( ИДчекета[1]);
UserОтвет = this.документыDataSet.Ответы.FindByОтветID ( ID_Ответа );
if (((CheckBox)Cntrl).Checked != UserОтвет.ДаНет) ПравилДаНет += 1;
if (((CheckBox)Cntrl).Checked == UserОтвет.ДаНет) НеПравилДаНет += 1;
}
}
вот кусок из моей программы, если так делеко залез то разберешся.
GSE==
Re: Скрытие различных элементов формы, указанных в списке
Пока ждал ответы, все таки решил своим способом
В решении используется пока 3 функции, одна из них рекурсивная:
Начальные циклы:
private void btnCheck_Click(object sender, EventArgs e)
{
foreach (Control ctrl in this.Controls)
{
foreach (DataRow row in viewAllTableAdapter1.GetData(tbxLogin.Text, this.Name.ToString())) //В row - список элементов
{
DisableControl(ctrl, row[2].ToString());
}
}
}
Функции:
private void DisableControl(Control ctrl, string item)
{
//Если это просто кнопка, то сразу затеняем при совпадении имен.
if (ctrl.GetType() == typeof(Button))
{
if (ctrl.Name == item)
{
ctrl.Enabled = false;
return;
}
}
//Обработка действий, если это ToolStrip
if (ctrl.GetType() == typeof(ToolStrip))
{
ProcessingMenu(ctrl, item);
}
//Обработка действий, если это MenuStrip
if (ctrl.GetType() == typeof(MenuStrip))
{
ProcessingMenu(ctrl, item);
}
if (ctrl.GetType() == typeof(StatusStrip))
{
ProcessingMenu(ctrl, item);
}
}
private void ProcessingMenu(Control ctrl, string item)
{
foreach (ToolStripItem it in (ctrl as ToolStrip).Items) //Для всех объектов
{
if (it.GetType() == typeof(ToolStripSplitButton)) //Если объект - выпадающий список по кнопке
{
foreach (ToolStripItem it_sub in (it as ToolStripSplitButton).DropDownItems)//Обход объектов по кнопке
{
ProcessingSubMenu(it_sub, item);
}
}
if (it.GetType() == typeof(ToolStripDropDownButton)) //Если объект - выпадающий список по кнопке
{
foreach (ToolStripItem it_sub in (it as ToolStripDropDownButton).DropDownItems)//Обход объектов по кнопке
{
ProcessingSubMenu(it_sub, item);
}
}
if (it.GetType() == typeof(ToolStripMenuItem)) //Если объект - выпадающий список по кнопке
{
foreach (ToolStripItem it_sub in (it as ToolStripMenuItem).DropDownItems)//Обход объектов по кнопке
{
ProcessingSubMenu(it_sub, item);
}
}
if (it.Name == item) //Если это не выпадающий список, а просто кнопка, то сразу затеняем.
{
it.Enabled = false;
return;
}
}
}
private void ProcessingSubMenu(ToolStripItem it, string item)
{
if (it.Name != item)
{
if (it.GetType() == typeof(ToolStripMenuItem))
{
if (it.Name != item)
{
foreach (ToolStripMenuItem it1 in (it as ToolStripMenuItem).DropDownItems)
{
ProcessingSubMenu(it1, item);
}
}
}
}
else
{
it.Enabled = false;
return;
}
}
Данный код корректно обрабатывает ToolStrip, MenuStrip, StatusStrip и простые контролы не в составе контейнеров. TabControl, ContextMenu и другие контейнеры сейчас делаю. Всем спасибо за ответы
Re[2]: Скрытие различных элементов формы, указанных в списке
Здравствуйте, Mdel, Вы писали:
M>Данный код корректно обрабатывает ToolStrip, MenuStrip, StatusStrip и простые контролы не в составе контейнеров. TabControl, ContextMenu и другие контейнеры сейчас делаю. Всем спасибо за ответы
Со всей ответственностью заявляю, что к получившемуся коду никакого отношения не имею.
Re[3]: Скрытие различных элементов формы, указанных в списке
Здравствуйте, Mdel, Вы писали:
M>Помогите с решением вопроса, буду очень благодарен за решение: M>C#. Net 2.0 M>Имеется список, содержащий имена объектов на форме, например: M>tbxOK — кнопка, M>tbxCancel — кнопка, M>toolstripItemDone — элемент MenuItem, M>ToolBtnInfo — элемент ToolStrip. M>Список этот динамически меняется и мне необходимо, пройдя по всем контролам формы, сделать Enable=false для элементов из списка. M>При проходе нижеследующим образом код работает только в том случае, если все контролы из списка являются кнопками, списками, текстовыми полями, т.е. у них родитель — основная форма:
А почему никто не сказал о Reflection. У меня например есть чудо класс для локализации(и не только) которму скармливается любой контрол и он не забывает ничего локализовать.
Re[2]: Скрытие различных элементов формы, указанных в списке
Здравствуйте, Ziggi111, Вы писали:
Z>Здравствуйте, Mdel, Вы писали:
M>>Помогите с решением вопроса, буду очень благодарен за решение: M>>C#. Net 2.0 M>>Имеется список, содержащий имена объектов на форме, например: M>>tbxOK — кнопка, M>>tbxCancel — кнопка, M>>toolstripItemDone — элемент MenuItem, M>>ToolBtnInfo — элемент ToolStrip. M>>Список этот динамически меняется и мне необходимо, пройдя по всем контролам формы, сделать Enable=false для элементов из списка. M>>При проходе нижеследующим образом код работает только в том случае, если все контролы из списка являются кнопками, списками, текстовыми полями, т.е. у них родитель — основная форма:
Z>А почему никто не сказал о Reflection. У меня например есть чудо класс для локализации(и не только) которму скармливается любой контрол и он не забывает ничего локализовать.
Я еще не дошел до изучения Reflection . Я, конечно, дописал приведенный мною выше вариант, теперь он обрабатывает любое вложение в любом количестве контейнеров, но должно же быть более изящное решение