Подтвердить что ты не робот

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

Резюме

Привет всем,
ОК, далее в мои приключения с настраиваемыми элементами управления...

Вкратце, вот что я узнал о трех основных "классах" пользовательских элементов управления. Пожалуйста, не стесняйтесь исправить меня, если это не так!

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

Мои мысли..

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

  • У вас мало/нет контроля над выходом HTML, что затрудняет "отладку".
  • CreateChildControls (и последующие методы) могут повсеместно работать с Controls.Add(myControl).
  • Я нашел таблицы рендеринга (будь то макет или контент), чтобы быть значительно неудобным.

Вопрос (ы)..

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

 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

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

Ответ 4

Я часто использую составные элементы управления. Вместо того, чтобы переопределять Render или RenderContents, просто назначьте каждый элемент управления CssClass и используйте таблицы стилей. Для нескольких элементов управления .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;
                           };

Ответ 5

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

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

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

Ответ 6

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

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

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

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