2010-02-09 28 views
1

Я разрабатываю набор настраиваемых элементов управления, один из которых является «родителем», любые другие должны быть добавлены внутри свойства ITemplate этого родителя.Вопрос времени разработки пользовательского контроля Asp.Net

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

Я хочу, чтобы эмулировать поведение аспида: Таблица и жерех: TableRow, вы не можете напрямую добавить жерех: TableRow за пределами осины: Таблица ...

Есть ли способ достичь этого ? Большое спасибо!

Редактировать: Я частично решил с предложением КП, но если вы прочтете комментарий, это не «реальный» способ сделать это (я думаю). Никто не знает, как это сделать? :(

ответ

2

Я отредактировал весь ответ на основе на нашем обсуждении. Вот пример работы и тестирования. У нас есть два элемента управления: ParentControl и ChildControl. ParentControl видна через Intellisense, где ChildControl видна только в виде ребенка ParentControl, как вы хотели. Для простых целей рендеринга дети отображают как теги li и ou tput их свойство «текст». Родительский элемент управления обеспечивает, чтобы каждый ребенок попросил отобразить его во время своего собственного события RenderContents.

Контроль за детьми: Контроль

using System.ComponentModel; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace TestControls 
{ 
    [ToolboxItem(false), Bindable(false)] 
    public class ChildControl : WebControl 
    { 
     protected override void Render(System.Web.UI.HtmlTextWriter writer) 
     { 
      base.Render(writer); 

      //render the text property as a list item for example's sake 
      writer.RenderBeginTag(HtmlTextWriterTag.Li); 
      writer.Write(this.Text); 
      writer.RenderEndTag(); 
     } 

     [Browsable(true)] 
     public string Text { get; set; } 
    } 
} 

Родитель:

using System.Collections.Generic; 
using System.ComponentModel; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace TestControls 
{ 
    [ToolboxData("<{0}:ParentControl runat=\"server\"></{0}:ParentControl>")] 
    [DefaultProperty("Children"), ParseChildren(true, "Children")] 
    public class ParentControl : WebControl 
    { 
     private List<ChildControl> _children; 

     protected override void RenderContents(HtmlTextWriter writer) 
     { 
      base.RenderContents(writer); 

      //create a div, and write some sample text 
      writer.RenderBeginTag(HtmlTextWriterTag.Div); 
      writer.Write("Parent Control. Children:"); 

      //create a ul, and ask each child control to render 
      writer.RenderBeginTag(HtmlTextWriterTag.Ul); 

      foreach (ChildControl child in _children) 
      { 
       child.RenderControl(writer); 
      } 

      //close all tags 
      writer.RenderEndTag(); 
      writer.RenderEndTag(); 
     } 

     [PersistenceMode(PersistenceMode.InnerDefaultProperty)] 
     public virtual List<ChildControl> Children 
     { 
      get 
      { 
       if (_children == null) 
        _children = new List<ChildControl>(); 

       return _children; 
      } 
     } 
    } 
} 

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

<%@ Register TagPrefix="test" Namespace="TestControls" %> 

А потом добавил некоторые разметка:

<test:ParentControl ID="test" runat="server"> 
    <test:ChildControl ID="child" Text="Hello World from Child 1" runat="server" /> 
    <test:ChildControl ID="child2" Text="Hello World from Child 2" runat="server" /> 
</test:ParentControl> 

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

Конечный результат:

Родительский контроль. Дети:

* Hello World from Child 1 
* Hello World from Child 2 

Кроме того, вот good article on how the whole intellisence creation works, который я последовал за создание выше.

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

+0

к моему субконтролю Я добавил [ToolboxItem (false)], затем я выставил его как свойство родительского элемента управления с атрибутом [PersistenceMode (PersistenceMode.InnerProperty)]. Я думаю, что это не «правильный» способ сделать это, но в это время единственный, кто делает трюк ... – tanathos

+0

Почему это «неправильный» способ? Я верю, что ты на правильном пути. Другой пример, использующий те же атрибуты: http://www.robertwray.co.uk/blog/2008/02/describing-aspnet-control-properties-declaratively.html –

+0

, потому что таким образом мой вспомогательный элемент управления не отображается автоматически, это просто свойство его родителя, я должен реализовать логику визуализации на родительском уровне ... честно говоря, я не понимаю, как работают asp: TableRow и asp: Table, я вижу их код в отражателе, но я не нашел причины, которая делает TableRow невидимым за пределами таблицы .... – tanathos

0

Я сделал это раньше, но у меня нет кода. Я могу сказать, что я понял это с помощью Reflector на встроенном элементе управления ASP.NET Datagrid. спроектируйте взаимосвязь между «содержащимися» («строка») и «контейнером» («сеткой»). Вы должны упорядочить классы вместе очень специфично, используя атрибуты.

Смежные вопросы