Как найти все компоненты на форме
Подскажите пожалуйста элементарный вопрос.
Как на форме перебрать все компоненты и найти тока нпример Комбабоксы.
Спасибо
10 ответов
288
17 октября 2008 года
nikitozz
1.2K / / 09.03.2007
Подскажите пожалуйста элементарный вопрос.
Как на форме перебрать все компоненты и найти тока нпример Комбабоксы.
Спасибо
Когда подобные вопросы задаете, указывайте хоть язык и среду. Тема называется «C/C++/C# — общие вопросы». Как-то гадать что вы используете не очень хочется.
41K
17 октября 2008 года
Turin
8 / / 14.10.2008
речь идет о C#
9.0K
17 октября 2008 года
t-34
129 / / 30.11.2007
this.Controls[]
11
17 октября 2008 года
oxotnik333
2.9K / / 03.08.2007
Подскажите пожалуйста элементарный вопрос.
Как на форме перебрать все компоненты и найти тока нпример Комбабоксы.
Спасибо
Код:
foreach (System.Windows.Forms.Control Comp in this.Controls)
{
System.Windows.Forms.ComboBox cmb = Comp as System.Windows.Forms.ComboBox;
}
9.0K
17 октября 2008 года
t-34
129 / / 30.11.2007
Код:
foreach (System.Windows.Forms.Control Comp in this.Controls)
{
System.Windows.Forms.ComboBox cmb = Comp as System.Windows.Forms.ComboBox;
}
только лучше это в try{}catch(){} поместить, поскольку если контрол не комбобокс, то будет исключение вылетать…
11
17 октября 2008 года
oxotnik333
2.9K / / 03.08.2007
зачем систему исключениями грузить?
Код:
foreach (System.Windows.Forms.Control Comp in this.Controls)
{
if (Comp.GetType().FullName == «System.Windows.Forms.ComboBox»)
{
System.Windows.Forms.ComboBox cmb = Comp as System.Windows.Forms.ComboBox;
}
}
288
17 октября 2008 года
nikitozz
1.2K / / 09.03.2007
только лучше это в try{}catch(){} поместить, поскольку если контрол не комбобокс, то будет исключение вылетать…
Почему это? Если контрол не комбобокс, то as просто вернет null.
9.0K
17 октября 2008 года
t-34
129 / / 30.11.2007
Почему это? Если контрол не комбобокс, то as просто вернет null.
извиняюсь, моя ошибка, вы ж использовали as, а не (). При использовании оператора as исключение не генерируется. еще раз сорри
41K
18 октября 2008 года
Turin
8 / / 14.10.2008
Всем большое спасибо
94K
11 июля 2014 года
Mazdorov
1 / / 11.07.2014
Данный метод замечательно подходит для поиска компонентов, которые являются наследниками класса System.Windows.Forms.Control. Как быть с компонентами наследниками System.ComponentModel.Component?
Every control that derives from Control has a Text property, which is every control — however for some controls this property does not have a meaning.
To build the complete list of controls you need to iterate the Form’s Controls collection and then, for each control within it, recursively iterate that control’s Controls collection.
IList<Control> controlsOnForm = new List<Control>();
BuildControlsList(this.Controls, controlsOnForm);
private static void BuildControlsList(ControlCollection controls, IList<Control> listToPopulate)
{
foreach (Control childControl in controls)
{
listToPopulate.Add(childControl);
BuildControlsList(childControl.Controls, listToPopulate);
}
}
I’m not actually sure how you are going to differentiate between controls that have a useful Text property and those for which it is not used. Obviously one approach would be to exclude those controls that have an empty string for the Text property.
One can also do something similar for the menu (note that you will need to modify this somewhat if you are using the MainMenuStrip):
IList<Menu> menusOnForm = new List<Menu>();
if (this.Menu != null)
{
menusOnForm.Add(this.Menu);
BuildMenuList(this.Menu.MenuItems, menusOnForm);
}
private static void BuildMenusList(MenuItemCollection menuItems, IList<Menu> listToPopulate)
{
foreach (Menu menuItem in menuItems)
{
listToPopulate.Add(menuItem);
BuildMenusList(menuItem.MenuItems, listToPopulate);
}
}
Свойство Items
содержит элементы типа ToolStripItem, а не Control. Они не унаследованы друг от друга, поэтому невозможно добавить тулстрипайтем в последовательность контролов.
Общим непосредственным предком этих классов является Component, у которого нет свойства Text
. Ни один из интерфейсов, которые они реализуют, тоже не имеет такого свойства. Поэтому в лоб ваша задача не решается.
Вы пишете, что не нашли ничего другого, как проверять тип. Да, тип придётся проверять в любом случае. Можно делать это внутри вашего метода и прямо там же выполнять необходимые действия.
Но если хочется внутри метода лишь найти все необходимые объекты, а действия с ними произвести снаружи, то могу предложить следующий код:
public static IEnumerable<Component> GetComponents(Control control)
{
foreach (Control childControl in control.Controls)
{
if (childControl is ToolStrip toolStrip)
{
foreach (ToolStripItem item in toolStrip.Items)
yield return item;
}
else
{
foreach (Component component in GetComponents(childControl))
yield return component;
}
yield return childControl;
}
}
Здесь мы получаем последовательность типа Component
, хотя с таким же успехом это могут быть object
— в любом случае далее придётся проверять их тип.
Можно избежать ручной проверки типов, используя dynamic
:
foreach (var component in GetComponents(this))
{
((dynamic)component).Text = "something";
}
Это более-менее рабочий код, но остаётся много вопросов. Например, ToolStrip
может содержать ToolStripDropDownButton, который не имеет свойства Items
, но имеет DropDownItems
. Сильно подозреваю, что по ним вы тоже хотели бы пройтись.
Всё это наводит на мысли, что вы не с той стороны подходите к решению некоей своей проблемы.
А вообще, я бы сделал два (или больше, с учётом DropDown
ов) метода, один из которых возвращал бы Control
, другой ToolStripItem
, третий — ToolStripDropDownItem
.
0 / 0 / 0 Регистрация: 16.12.2011 Сообщений: 28 |
|
1 |
|
Получение всех обектов формы08.08.2013, 14:44. Показов 3512. Ответов 2
Есть форма и на ней много различных объектов (textbox, layer, radiobutton…). Как получить список/массив перечесления всех обектов, которые есть на форме?
0 |
708 / 708 / 226 Регистрация: 04.03.2013 Сообщений: 1,384 |
|
08.08.2013, 15:17 |
2 |
this.Controls
1 |
Cupko 648 / 582 / 171 Регистрация: 17.07.2012 Сообщений: 1,651 Записей в блоге: 1 |
||||
08.08.2013, 15:25 |
3 |
|||
Решение
1 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
08.08.2013, 15:25 |
3 |
- Главная
- Поиск «пропавших» компонентов
Иногда бывает, что не можете найти на форме компонент, который на ней присутствует. Это бывает по нескольким причинам. Например, если вы используете метку типа TLabel, установив в ней свойство AutoSize (автоматическое изменение размера по размерам надписи) в true и стерев значение надписи Caption, то горизонтальный размер метки уменьшается до нуля и ее не будет видно на форме, пока во время выполнения приложения значение Caption не изменится. Компонент может «пропасть» также, если он накрыт другим компонентом, расположенным выше в Z-последовательности. Возможны и некоторые другие причины, например, такой выбор цветов, что компонент сливается с фоном.
Найти «пропавший» компонент можно, выбрав его имя в выпадающем списке, расположенном вверху окна Инспектора Объектов. Этот список содержит все компоненты, размещенные на форме. Если вы выберете в нем нужный компонент, то на форме вокруг него появится рамка с маркерами, видимая даже в случае, если компонент накрыт сверху какой-нибудь панелью или другим компонентом. При этом в Инспекторе Объектов станут видны страницы свойств и событий найденного компонента.
Если цель поиска заключалась в том, чтобы задать для компонента значения каких-то свойств или обработчики событий, то больше вам ничего и не надо. Если же вам все-таки надо добраться до компонента, накрытого другим компонентом или панелью, то придется или временно сдвигать куда-то эти помехи, или выполнить для них команду Send То Back, которая сдвинет их в низ Z-последовательности. По крайней мере, вы знаете, где расположен «беглец» и что надо сдвинуть, чтобы его найти.
Еще один способ найти компонент на форме это выделение его вершины в окне Дерева Объектов.
Особо надо остановиться на вопросе, как, ничего не сдвигая, добраться до нижних панелей, если на них лежат другие панели, или как добраться до формы, если вся она накрыта панелями. Здесь возможен тот же подход, о котором говорилось выше. Но можно поступить проще. Выделите верхнюю панель и нажмите клавишу Esc. В окне Инспектора Объектов откроются страницы, связанные с нижележащей панелью. Нажмите Esc еще раз и откроются страницы следующего слоя и т.д. до тех пор, пока не откроются страницы формы. Конечно, если у вас есть только один слой панели, то страницы формы откроются при первом же нажатии Esc.
Табаков Юрий
Программист
Автор и редактор проекта CuBook.PRO. Главная задача, которую я ставлю перед собой – донести до начинающих программистов удобочитаемый материал. Буду рад выслушать замечания и предложения. Не забываем ставить оценки и делать репосты =)