Как получить список компонентов из элемента управления? - PullRequest
2 голосов
/ 04 августа 2009

У меня есть компонент, полученный из ErrorProvider. У меня есть BaseForm и BaseUserControl, в каждый из которых добавлен этот пользовательский ErrorProvider, добавленный в конструктор. У меня есть много вложенных BaseUserControls на BaseForm и других BaseUserControls, и мне нужно найти все пользовательские ErrorProviders на вложенных элементах управления из формы верхнего уровня или пользовательского элемента управления для доступа к специальным функциям.

Как пройти через все вложенные элементы управления и найти все компоненты ErrorProvider? Например:

List<ErrorProviderEx> customProviders = GetErrorProviders(myUserControl);

Самое близкое, что я получил, - это рекурсивный метод, который просматривает myUserControl.Controls и проверяет коллекцию Control.Container.Components каждого элемента управления, но это приводит к некоторой сумасшедшей логике, когда приходится смотреть назад в рекурсивном вызове на элемент Container элемента управления. , Я также пытаюсь избежать использования отражения.

Ответы [ 2 ]

2 голосов
/ 04 августа 2009

Компоненты Form или UserControl не представлены ни в одной коллекции. Тебе придется сделать это самому.

Сначала объявите интерфейс, который будут реализовывать ваши UserControl:

public interface IComponentList
{
  List<Component> Components
  {
    get;
  }
}

Затем, в вашем UserControl, добавьте компоненты в список в конструкторе и предоставьте этот список через свойство интерфейса Components:

public partial class UserControl1 : UserControl, IComponentList
{
  private List<Component> _components = new List<Component>();

  public UserControl1()
  {
    InitializeComponent();

    _components.Add(errorProvider1);
  }

  List<Component> IComponentList.Components
  {
    get
    {
      return _components;
    }
  }
}

Теперь следующая функция должна получить список ErrorProvider с на всех UserControl с, которые реализуют интерфейс IComponentList:

public List<ErrorProvider> GetErrorProviders(Control myControl)
{
  List<ErrorProvider> foundErrorProviders = new List<ErrorProvider>();
  GetErrorProviders(myControl, foundErrorProviders);
  return foundErrorProviders;
}

protected void GetErrorProviders(Control myControl, List<ErrorProvider> foundErrorProviders)
{
  if (foundErrorProviders == null)
  {
    throw new ArgumentNullException("foundErrorProviders");
  }
  if (myControl is IComponentList)
  {
    foreach (Component component in ((IComponentList) myControl).Components)
    {
      if (component is ErrorProvider)
      {
        foundErrorProviders.Add((ErrorProvider) component);
      }
    }
  }
  foreach (Control control in myControl.Controls)
  {
    GetErrorProviders(control, foundErrorProviders);
  }
}

Вызовите метод следующим образом:

GetErrorProviders(myUserControl);

Примечание: Конструктор Windows Forms помещает все компоненты в переменную с именем components в файле .designer.cs. Вы можете просто добавить все компоненты из коллекции components в список _components, но я прочитал следующее здесь :

[...] Я понял, что components член фактически используется только когда компонент, имеющий конкретный конструктор помещается на Форма. [...] Если компонент предоставляет конструктор с конкретной подписью Public Sub Новый (ByVal c As IContainer), затем components Элемент формы создан и передается компоненту Конструктор

... вот почему я не решаюсь использовать коллекцию components, поскольку она не обязательно будет содержать все ваши компоненты. будет работать с ErrorProvider, хотя.

Возможно, вы захотите взглянуть и на это сообщение на форуме .

0 голосов
/ 26 августа 2014

У меня было похожее требование в том, что мне нужно было найти и сослаться на экземпляры ErrorProvider в UserControls, производных от пользовательского базового класса пользовательского элемента управления. Я использовал отражение в базовом классе, чтобы сделать это. Код показан ниже (в VB.NET).

    Protected ErrorProvidersList As List(Of ErrorProvider) = New List(Of ErrorProvider)()

    Protected Overrides Sub OnLoad(e As EventArgs)
    MyBase.OnLoad(e)
    '' Get a collection of error providers that will allow us to check for errors
    For Each fi As FieldInfo In Me.[GetType]().GetFields(BindingFlags.NonPublic Or BindingFlags.Instance)
        Dim obj As Object = fi.GetValue(Me)
        If TypeOf obj Is ErrorProvider Then
            ErrorProvidersList.Add(obj)
        End If
    Next
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...