Доступ к UserControls из UserControls без необходимости полагаться на FindControl - PullRequest
0 голосов
/ 28 октября 2009

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

Удивительно, я слышал, как вы говорите, но что произойдет, когда я хочу, чтобы два из этих пользовательских элементов управления общались друг с другом? элемент управления формы поиска и элемент управления результатами поиска. Это была проблема, с которой я недавно столкнулся и нашел решение, которым я вполне доволен, но подумал, что я ее расскажу и посмотрю, что вы все думаете.

Во-первых, я быстро решил проигнорировать метод FindControl, любое решение, которое я мог придумать, включало его в грязь и заставило меня немного умереть внутри.

РЕДАКТИРОВАТЬ: решение не использовать FindControl связано с тем, что он выполняет поиск только в коллекции дочерних элементов управления и, следовательно, потребует циклического перебора элементов управления, чтобы найти тот, который я хочу.

Это то, что я имею до сих пор: Добавил глобальное открытое свойство в мой базовый класс страниц под названием BasePage:

public SortedList<string, CustomUserControl> CustomControls { get; set; }

Добавлено общедоступное свойство в мой базовый пользовательский класс управления с именем CustomUserControl:

protected SortedList<string, CustomUserControl> CustomControls
{
    get 
    {
        BasePage page = Page as BasePage;
        if (page != null)
            return page.CustomControls;
        else
            return null;
    }
}

В Page_Init моих UserControls добавлена ​​ссылка на элемент управления в коллекцию CustomControl, которая присваивает его свойству BasePage.

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

if (this.CustomControls.ContainsKey("SearchForm"))
    searchForm = this.CustomControls["SearchForm"] as SearchForm;

Это основа, я уточняю, как пишу, так что, пожалуйста, не стесняйтесь разбирать его на части. Если у кого-нибудь из вас есть лучшее / альтернативное решение, я бы хотел услышать его. Или даже если вы прочитали статью об этой проблеме, Google не сильно мне помог в моих поисках.

Ответы [ 2 ]

0 голосов
/ 05 ноября 2009

Как вы говорите, FindControl просматривает только непосредственные дочерние элементы контейнеров, поэтому вам придется перебирать их все, чтобы найти элемент управления. Почему это проблема? Если вы сделаете функцию рекурсивной, то в итоге получится всего несколько строк кода. Если вы сделаете его расширением класса Control, у вас будет удобный доступ к функции.

Например:


    public static class ControlExtensions
    {
        public static Control FindControl(this Control control, string id, bool Recursive)
        {
            var result = control.FindControl(id);
            if (!Recursive) return result;
            if (result == null)
            {
                foreach (Control child in control.Controls)
                {
                    result = child.FindControl(id, true);
                    if (result != null) return result;
                }
            }
            return null;
        }
    }

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

Я не понимаю вашего нежелания использовать FindControl. Подумайте о том, как Microsoft решила эту же проблему ... В частности, контролирует валидатор. У них просто есть свойство ControlToValidate, которое принимает идентификатор другого элемента управления в виде строки. Внутренне он, вероятно, просто использует FindControl. (ну, честно говоря, я не знаю, но, похоже, вероятная ставка)

Ваше решение кажется несколько избыточным, потому что объект Page уже имеет коллекцию всех элементов управления. И это работает только в вашем конкретном контексте.

Редактировать: Кстати, я только что посмотрел на встроенные валидаторы, и они действительно просто используют FindControl. Может быть, я неправильно понимаю ваши требования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...