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

Резюме

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

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

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

Мои мысли..

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

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

Вопросы)..

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

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

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

Я с нетерпением жду ваших ответов ^ _ ^

20.08.2008 07:49:06
6 ОТВЕТОВ
РЕШЕНИЕ

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

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

5
20.08.2008 07:53:32

Я часто использую составные элементы управления. Вместо переопределения 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;
                           };
1
20.08.2008 08:02:18

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

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

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

1
20.08.2008 10:27:56

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

 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);
 }
3
20.04.2017 15:22:37

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

2
20.08.2008 19:44:35

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

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

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

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

0
16.09.2008 11:20:20