Пользовательские элементы управления ASP.NET — композиты

StackOverflow https://stackoverflow.com/questions/17532

Вопрос

Краткое содержание

Всем привет,
Хорошо, продолжаем мои приключения с пользовательским управлением...

Подводя итог, я узнал о трех основных «классах» пользовательских элементов управления.Пожалуйста, поправьте меня, если что-то из этого не так!

  1. Пользовательские элементы управления - Которые наследуют от Пользовательский контроль и содержатся внутри ASCX файл.Они довольно ограничены в возможностях, но представляют собой быстрый и простой способ добиться некоторой общности пользовательского интерфейса при поддержке дизайнеров.
  2. Пользовательские составные элементы управления - Это элементы управления, которые наследуются от ВебКонтроль где вы добавляете уже существующие элементы управления к элементу управления внутри Создать дочерние элементы управления метод.Это обеспечивает большую гибкость, но отсутствие поддержки дизайнера без дополнительного кодирования.Однако они очень портативны, поскольку их можно скомпилировать в DLL.
  3. Пользовательские визуализированные элементы управления — Подобно настраиваемым составным элементам управления, они добавляются в проект библиотеки веб-элементов управления.Отрисовка элемента управления полностью контролируется программистом путем переопределения Оказывать метод.

Мои мысли..

Итак, играя с пользовательскими композитами, я обнаружил следующее:

  • У вас мало/нет контроля над выводом HTML, что затрудняет «отладку».
  • А Создать дочерние элементы управления (и последующие методы) могут быть очень заняты Controls.Add(myControl) повсюду.
  • Я обнаружил, что рендеринг таблиц (будь то макет или контент) довольно неудобен.

Вопросы)..

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

  • Используете ли вы композиты?
  • Есть ли у вас какие-нибудь хитрости для управления выводом HTML?
  • Вы просто скажете «к черту все это» и создадите собственный визуализируемый элемент управления?

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

Жду ваших ответов ^_^

Это было полезно?

Решение

Я говорю: давайте приступим к созданию пользовательского элемента управления.Я считаю, что в большинстве случаев композицию проще сделать и использовать в UserControl, но если что-то выходит за рамки этого, вам понадобится более тонкая степень контроля (непреднамеренный каламбур), чтобы заслужить вашу собственную стратегию рендеринга.

Могут быть элементы управления, которые достаточно просты, чтобы заслуживать составного элемента (например, текстовое поле в сочетании с средством выбора даты на основе javascript/dhtml), но помимо этого одного примера, похоже, что пользовательские отображаемые элементы управления — это путь.

Другие советы

Вот еще один метод расширения, который я использую для пользовательского рендеринга:

 public static void WriteControls
        (this HtmlTextWriter o, string format, params object[] args)
 { 
    const string delimiter = "<2E01A260-BD39-47d0-8C5E-0DF814FDF9DC>";
    var controls  = new Dictionary<string,Control>();

    for(int i =0; i < args.Length; ++i)
    { 
       var c = args[i] as Control; 
       if (c==null) continue;
       var guid = Guid.NewGuid().ToString();
       controls[guid] = c;
       args[i] = delimiter+guid+delimiter;
    }

    var _strings = string.Format(format, args)
                         .Split(new string[]{delimiter},
                                StringSplitOptions.None);
    foreach(var s in _strings)
    { 
       if (controls.ContainsKey(s)) 
           controls[s].RenderControl(o);
       else 
           o.Write(s);
    }
}

Затем, чтобы отобразить пользовательский композит в методе RenderContents(), я пишу следующее:

protected override void RenderContents(HtmlTextWriter o)
{ 
    o.WriteControls
         (@"<table>
               <tr>
                    <td>{0}</td>
                    <td>{1}</td>
               </tr>
             </table>"
            ,Text
            ,control1);
 }

Роб, ты прав.Подход, о котором я упомянул, является своего рода гибридом.Преимущество наличия файлов ascx заключается в том, что в каждом проекте, который я видел, дизайнерам будет удобнее редактировать реальную разметку, а с ascx вы и дизайнер можете работать отдельно.Если вы не планируете вносить изменения CSS/разметки/дизайна в сами элементы управления позже, вы можете использовать собственный визуализируемый элемент управления.Как я уже говорил, мой подход актуален только для более сложных сценариев (и именно там, наверное, нужен дизайнер :))

Я часто использую составные элементы управления.Вместо переопределения Render или RenderContents просто назначьте каждому элементу управления CssClass и используйте таблицы стилей.Для нескольких Controls.Add я использую метод расширения:

//Controls.Add(c1, c2, c3)
static void Add(this ControlCollection coll, params Control[] controls)
 { foreach(Control control in controls) coll.Add(control);
 }

Для быстрого и грязного рендеринга я использую что-то вроде этого:

writer.Render(@"<table>
                   <tr><td>{0}</td></tr>
                   <tr>
                       <td>", Text);
control1.RenderControl(writer);
writer.Render("</td></tr></table>");

Для инициализации свойств элемента управления я использую синтаксис инициализатора свойств:

childControl = new Control {  ID="Foo"
                            , CssClass="class1"
                            , CausesValidation=true;
                           };

Использование пользовательских составных элементов управления имеет смысл в ситуации, когда у вас большое веб-приложение и вы хотите повторно использовать большие фрагменты во многих местах.Тогда вы будете добавлять только дочерние элементы управления к тем, которые разрабатываете, вместо того, чтобы повторяться.Недавно над большим проектом, над которым я работал, мы сделали следующее:

  • Каждый составной элемент управления имеет контейнер.Используется как оболочка для всего внутри элемента управления.
  • Каждый составной элемент управления имеет шаблон.Файл ascx (без директивы <%Control%>), содержащий только разметку шаблона.
  • Контейнер (который сам по себе является элементом управления) инициализируется из шаблона.
  • Контейнер предоставляет свойства для всех остальных элементов управления в шаблоне.
  • Вы используете this.Controls.Add([the_container]) только в своем составном элементе управления.

На самом деле вам нужен базовый класс, который будет инициализировать контейнер с указанным шаблоном, а также генерировать исключения, когда элемент управления не найден в шаблоне.Конечно, для небольшого приложения это, скорее всего, будет излишним.Если у вас нет повторно используемого кода и разметки и вы хотите писать только простые элементы управления, вам лучше использовать пользовательские элементы управления.

Возможно, вы сможете использовать этот метод, чтобы упростить время разработки:

http://aspadvice.com/blogs/ssmith/archive/2007/10/19/Render-User-Control-as-String-Template.aspx

По сути, вы создаете экземпляр пользовательского элемента управления во время выполнения с помощью метода LoadControl, затем передаете ему какой-либо пакет состояний, а затем прикрепляете его к дереву элементов управления.Таким образом, ваш составной элемент управления фактически будет функционировать как контроллер, а файл .ascx будет похож на представление.

Это избавит вас от необходимости создавать экземпляр всего дерева элементов управления и стилизовать его на C#!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top