问题
My application interface provides end-user input to create markup, that of which I'm using a templated control for:
<me:MyControl>
<TemplateA>
I'm inside of an ITemplate
</TemplateA>
<TemplateB>
So what, I am too.
</TemplateB>
</me:MyControl>
I need to allow duplicate control ID's within web controls inside of these templates. Now I know I can't have a duplicate ID inside of a single template, but I can do this:
<me:MyControl>
<TemplateA>
<me:Textbox Id="ABC" />
</TemplateA>
<TemplateB>
<me:Textbox Id="ABC" />
</TemplateB>
</me:MyControl>
What I want to do is instead of making the templates via property:
<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
I want to make them by using a custom class type that Implements ITemplate. However, when I do this, I get errors about duplicate IDs:
Here's an example: https://msdn.microsoft.com/en-us/library/0e39s2ck.aspx
That way I can have properties and even override the control builder class to pull in custom controls without ugly markup.
So instead of this:
<me:MyControl>
<TemplateA>
<me:BaseControl Hello="World" Foo="Bar">
More controls inside
</me:BaseControl>
</TemplateA>
</me:MyControl>
I can do this:
<me:MyControl>
<TemplateA Hello="World" Foo="Bar">
More controls inside
</TemplateA>
</me:MyControl>
So ultimately, more than anything this is all about solving the duplicate control ID issue, and I need the end user to have the ability to set this ID, so leaving out the IDs is out of the question. I want to be able to do this:
<me:MyControl>
<TemplateA PropertyA="Hello" PropertyB="World">
<asp:Textbox Id="Test" />
</TemplateA>
<TemplateA PropertyA="Foo" PropertyB="Bar">
<asp:Textbox Id="Test" />
</TemplateA>
</me:MyControl>
So, I need to be able to have duplicate IDs within their own instance of the control, which I know no other way to do this other than them being inside of a template, but I don't want templateA, templateB, etc. I need to be able to pass properties to these templates (building them as a class instead of an inner property, but still getting duplicate ID errors when I do it this way).
I wrote my examples in vb.net, but C# support is welcome. This is an asp.net question in general.
回答1:
Try 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))
}));
}
}
}
}
来源:https://stackoverflow.com/questions/39322405/asp-net-duplicate-ids-and-templated-control-is-there-a-more-elegant-way