Asp.Net Custom Control вопрос времени разработки - PullRequest
1 голос
/ 09 февраля 2010

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

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 09 февраля 2010

Я отредактировал весь ответ на основе нашего обсуждения. Вот рабочий и проверенный пример. У нас ниже двух элементов управления - ParentControl и ChildControl. ParentControl отображается через Intellisense, где ChildControl отображается только как дочерний элемент ParentControl, как вы и хотели. Для простых целей рендеринга дети отрисовывают как теги li и выводят свое свойство 'text'. Родительский элемент управления обеспечивает отображение каждого дочернего элемента во время его собственного события 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

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

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

0 голосов
/ 09 февраля 2010

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

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