Как добавить дочерние узлы в пользовательский элемент управления asp.net, полученный из System.Web.UI.Control - PullRequest
6 голосов
/ 04 сентября 2010

Я хотел бы знать, как добавить несколько дополнительных дочерних узлов в пользовательский класс элементов управления, производный от System.Web.UI.Control.

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

<cust:MyCustomControl id="ctlMyCustomControl" runat="server" attribute1="somevalue" attribute2="somevalue" ></MyCustomControl>

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

<cust:MyCustomControl id="ctlMyCustomControl" runat="server" attribute1="somevalue" attribute2="somevalue" >
  <childnode1>value1</childnode1>
  <childnode2>value2</childnode2>
</MyCustomControl>

Мне не понятно, как получить доступ к дочерним узлам.

Любое понимание того, как это сделать, приветствуется.

Ответы [ 2 ]

6 голосов
/ 04 сентября 2010

Вы хотите иметь возможность описывать свойства элемента управления asp.net декларативно .

Чтобы иметь возможность иметь следующую разметку:

<Abc:CustomControlUno runat="server" ID="Control1">
    <Children>
        <Abc:Control1Child IntegerProperty="1" StringProperty="Item1" />
        <Abc:Control1Child IntegerProperty="2" StringProperty="Item2" />
    </Children>
</Abc:CustomControlUno>

Вам нужнаследующий код:

[ParseChildren(true)]
[PersistChildren(true)]
[ToolboxData("<{0}:CustomControlUno runat=server></{0}:CustomControlUno>")]
public class CustomControlUno : WebControl, INamingContainer
{
    private Control1ChildrenCollection _children;

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Control1ChildrenCollection Children
    {
        get
        {
            if (_children == null)
                _children = new Control1ChildrenCollection();
            return _children;
        }
    }
}

public class Control1ChildrenCollection : List<Control1Child>
{
}

public class Control1Child
{

    public int IntegerProperty { get; set; }
    private string StringProperty { get; set; }
}
4 голосов
/ 04 сентября 2010

Если вы хотите поддержать данный синтаксис как есть (без необходимости использовать префиксы тега), вы можете использовать ControlBuilder:

 //MyControlBuilder 
 public class MyControlBuilder : ControlBuilder
 {
   public override Type GetChildControlType(string tagName, IDictionary attribs)
   { 
     if (tagName.StartsWith("childnode")) return typeof(Control);
     else return base.GetChildControlType(tagName,attribs);
   }

   public override void AppendLiteralString(string s)
   { 
     //ignore literals betwen tags
   }
 }

 //MyCustomControl
 [ParseChildren(false)]
 [ControlBuilder(typeof(MyControlBuilder))]
 public class MyCustomControl : Control
 {
   public string attribute1 {get;set;}
   public string attribute2 {get;set;}

   protected override void AddParsedSubObject(object obj)
   {
     Control ctrl = (Control) obj;
     LiteralControl childNode = ctrl.Controls[0];

     //Add as-is (e.g., literal "value1")
     Controls.Add(childNode);
   }
 }

См. Также http://msdn.microsoft.com/en-us/library/system.web.ui.controlbuilder.aspx

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