views:

50

answers:

1

Hello

I've created a user control that takes content from an XML file and renders the content on the page. Fairly straight-forward stuff.

However it's come up that I may need to replace portions of the content based on id with other manual content.

My idea is to expose a repeatable property within the user control's declaration like this:

<my:XmlRenderSource ID="XmlRenderSource1" runat="server" XmlUrl="xml/sample.xml">
    <OverrideContent targetId='thingToReplaceId'><p>New Content</p></OverrideContent>
    <OverrideContent  targetId='thingToReplaceId2'><p>New Content</p></OverrideContent>
</my:XmlRenderSource>

So far I have the following in my userControl (i've trimmed out the useless stuff):

 public class OverrideContent
    {
        public string targetId { get; set; }
    }

    public class OverrideContentCollection : List<OverrideContent>
    {

    }


[
      ParseChildren(
  typeof(OverrideContent),
  DefaultProperty = "OverrideItems",
  ChildrenAsProperties = true
  )
  ]
public partial class XmlRenderSource : System.Web.UI.UserControl
    {
        private string xmlUrl = "";
        private string xmlUrlBase = "";

          public OverrideContentCollection OverrideItems
          {
          get;
          set;
          }
// Loads of other code that doesn't matter for this
}

Where on load or pre render I loop through the OverrideContent items and replace portions of the xml before render. I understand how I can do that, but I am having a distinct problem exposing the OverrideContent items as a repeatable property.

I know it can be done, but for the life of me I cannot get it going. If anyone could provide a crash-course on how to do this, I would be eternally grateful.

+1  A: 

You can try with something like that:

[ParseChildren(typeof(OverrideContent), DefaultProperty = "OverrideItems", ChildrenAsProperties=true)]
public partial class XmlRenderSource : System.Web.UI.UserControl
{
    private OverrideContentCollection overrideItems = new OverrideContentCollection();

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
    public OverrideContentCollection OverrideItems
    {
        get { return overrideItems; }
    }
}

I used this page as a test:

<%@ Register Src="XmlRenderSource.ascx" TagName="XmlRenderSource" TagPrefix="uc1" %>
<%@ Register Namespace="WebApplication2" TagPrefix="uc1" Assembly="WebApplication2" %>
...

<uc1:XmlRenderSource ID="XmlRenderSource1" runat="server">
    <uc1:OverrideContent targetId="test">Content</uc1:OverrideContent>
    <uc1:OverrideContent targetId="test2" />
</uc1:XmlRenderSource>

EDIT: If you need to put some text into each OverrideElement, this is one way to do it (I also updated the test page above):

[ParseChildren(true, "text")]
public class OverrideContent
{
    public string targetId { get; set; }

    [PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)]
    public string text { get; set; }
}
Johann Blais
That's close to what I need, but then I need to be able to add content to the middle of the OverrideContent object. Everything I've read so far disallows putting content between usercontrols, so I think I need to create a custom control, which isn't showing up, despite my adding it to the assembly list etc. If you can tell me how to get the innerHTML of those controls, that'll be exactly what I need.
cdutson
I don't understand what you mean by "putting content between usercontrols". Do you want to add plain text between the OverrideContent elements? Or plain text between the opening and closing tag of the OverrideContent elements ?
Johann Blais
Refer to my initial example to see what I mean. Basically all of the content within the usercontrol open and close tags, I want to store, but not render. I then want to use that stored information to replace content in the XML document. I know how to do the actual replacement, but it's the content between the usercontrol tags that I can't figure out.
cdutson
OK I updated my answer accordingly.
Johann Blais
I had to make a slight alteration to the second part, as it doesn't seem to like having a class without a type. I've made it into a Web Control and that seems to work. Thank you very much for all the help. Enjoy the bounty!
cdutson