【问题标题】:ASP.NET, Duplicate IDs, and Templated Control... Is there a more elegant way?ASP.NET、重复 ID 和模板化控件……还有更优雅的方法吗?
【发布时间】:2016-09-04 23:40:04
【问题描述】:

我的应用程序界面提供最终用户输入来创建标记,我正在使用模板化控件:

<me:MyControl>
  <TemplateA>
    I'm inside of an ITemplate
  </TemplateA>
  <TemplateB>
    So what, I am too. 
  </TemplateB>          
</me:MyControl>

我需要在这些模板内的 Web 控件中允许重复的控件 ID。现在我知道我不能在单个模板中拥有重复的 ID,但我可以这样做:

<me:MyControl>
  <TemplateA>
    <me:Textbox Id="ABC" />
  </TemplateA>
  <TemplateB>
    <me:Textbox Id="ABC" />
  </TemplateB>          
</me:MyControl>

我想要做的不是通过属性制作模板:

<TemplateContainer(GetType(HelloWorld))>
<PersistenceMode(PersistenceMode.InnerProperty)>
Public Property TemplateA() As ITemplate

Protected Overrides Sub CreateChildControls()

  If TemplateA IsNot Nothing Then TemplateA.InstantiateIn(Me)
  If TemplateB IsNot Nothing Then TemplateB.InstantiateIn(Me)
  MyBase.CreateChildControls()

End Sub

我想通过使用实现 ITemplate 的自定义类类型来制作它们。但是,当我这样做时,我会收到有关重复 ID 的错误:

这是一个例子:https://msdn.microsoft.com/en-us/library/0e39s2ck.aspx

这样我就可以拥有属性,甚至可以覆盖控件构建器类来引入自定义控件,而不会出现丑陋的标记。

所以不要这样:

<me:MyControl>
  <TemplateA>
    <me:BaseControl Hello="World" Foo="Bar">
      More controls inside
    </me:BaseControl>
  </TemplateA>
</me:MyControl>

我可以这样做:

<me:MyControl>
  <TemplateA Hello="World" Foo="Bar">
    More controls inside        
  </TemplateA>
</me:MyControl>

因此,最终,最重要的是解决重复控件 ID 问题,我需要最终用户能够设置此 ID,因此省略 ID 是不可能的。我希望能够做到这一点:

<me:MyControl>
  <TemplateA PropertyA="Hello" PropertyB="World">
    <asp:Textbox Id="Test" />        
  </TemplateA>
  <TemplateA PropertyA="Foo" PropertyB="Bar">
    <asp:Textbox Id="Test" />        
  </TemplateA>
</me:MyControl>

所以,我需要能够在它们自己的控件实例中拥有重复的 ID,除了它们在模板中之外,我不知道其他方法可以做到这一点,但我不想要 templateA、templateB、等等。我需要能够将属性传递给这些模板(将它们构建为类而不是内部属性,但是当我这样做时仍然会出现重复的 ID 错误)。

我在 vb.net 中编写了我的示例,但欢迎 C# 支持。这是一个一般的 asp.net 问题。

【问题讨论】:

    标签: c# asp.net vb.net custom-controls


    【解决方案1】:

    试试 xml linq

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string xmlHeader = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
                    "<Root xmlns:me =\"abc\" xmlns:asp =\"def\"></Root>";
                XDocument doc = XDocument.Parse(xmlHeader);
                XElement root = (XElement)doc.FirstNode;
                XNamespace meNs = root.GetNamespaceOfPrefix("me");
                XNamespace aspNs = root.GetNamespaceOfPrefix("asp");
    
                XElement control = new XElement(meNs + "MyControl");
                root.Add(control);
    
                var inputs = new[] {
                   new { PropertyA="Hello", PropertyB="World", Id="Test"},
                   new { PropertyA="Foo", PropertyB="Bar", Id="Test"},
                };
    
                foreach (var input in inputs)
                {
                    control.Add(new XElement("TemplateA", new object[] {
                        new XAttribute("PropertyA", input.PropertyA),
                        new XAttribute("PropertyB", input.PropertyB),
                        new XElement(aspNs + "Textbox", new XAttribute("Id", input.Id))
                     }));
                }
            }
        }
    }
    

    【讨论】:

    • 我未能对此作出回应,因此我深表歉意。当允许用户操作模板化控件并使用 controlbuilder 解析 ascx 文件的内容时,我看不出这将如何工作。
    猜你喜欢
    • 1970-01-01
    • 2016-10-09
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 2015-12-12
    • 1970-01-01
    相关资源
    最近更新 更多