Thursday, December 02, 2004

Complex Properties with Inner Property Persistence persisting a Collection property in a User Custom Control using Code Beside Method

Man that's one long name. I'm so excited to blog about this!

Here's the case, I've been trying to learn how to embed custom tags within custom tags. Basically in ColdFusion, a custom tag is the same as a Custom Control. It's much easier to do it in ColdFusion, but that's another story.

So I was actually trying out templated controls, but it turned out it wasn't really what I wanted. Templated Controls are basically almost empty controls that exposes it's structure for you to change accordingly. Which is not what I really want.

Then I came upon something that fits the description. To pass in multiple XML-like "data" into the user custom control. NOTE: USER CUSTOM CONTROL. Very important note there.

Anyway, it's basically called inner property. This is how to create an Inner Property.

// your other methods and whatsoever. I'll skip to the property
[NotifyParentProperty(true), PersistenceMode(PersistenceMode.InnerProperty)]
public void MyClassWithInnerProp MyInnerProp {
  get { .... }
  set { .... }
}

As simple as that. And the html side would be like this.

<mytag:mycontrol runat="server">
  <MyInnerProp />
</mytag:mycontrol>

Basically something like that. Wonderful right? That's exactly what I needed. But wait! What if I needed a collection of the same property? Hell breaks loose. Something along the lines like THIS.

<mytag:mycontrol runat="server">
  <MyInnerProp />
  <MyInnerProp />
  <MyInnerProp />
  <MyInnerProp />
</mytag:mycontrol>

The twist is, to create a collection of properties, you'll have to specify this attribute in your control class. Something like this.

[ParseChildren(true,"MyCollecProp")] // where MyCollecProp is your collection property
public class MyControl : WebControl {
  //blah blah blah
  [NotifyParentProperty(true), PersistenceMode(PersistenceMode.InnerDefaultProperty)]
  public MyCollectPropClass MyCollecProp {
    get { ... }
    set { ... }
  }
}

Ok. A few things to note. PersistenceMode.InnerProperty is now changed to PersistenceMode.InnerDefaultProperty. And you HAVE to specify your default property in the ParseChildren(true, "MyCollecProp").

Here comes the problem. What if I want this collection property in my User Custom Control? How do I do it? I can't put an attribute tag when doing Code Beside. You might be able to do it with Code Behind. Anyway, simply enough, I combine the 2 methods, by creating 1 Inner Property which is a Control which this Control has a Collection Property! WOAH! Fantastic!

Here's the code.

// your other methods and whatsoever. I'll skip to the property
[NotifyParentProperty(true), PersistenceMode(PersistenceMode.InnerProperty)]
public void MyControl MyInnerProp { // Notice the change to MyControl
  pget { .... }
  set { .... }
}

// THIS HAS TO BE IN A CS FILE AND COMPILED IN A DLL THEN ADD THE @ REGISTER TO THE
// PAGES INVOLVED (mainly the User Custom Control and your Page using the control)
[ParseChildren(true,"MyCollecProp")] // where MyCollecProp is your collection property
public class MyControl : WebControl {
  //blah blah blah
  [NotifyParentProperty(true), PersistenceMode(PersistenceMode.InnerDefaultProperty)]
  public MyCollectPropClass MyCollecProp {
    get { ... }
    set { ... }
  }
}

And the html would be something like this.

<mytag:MyUserControl runat="server">
  <MyInnerProp>
    <MyCollecProp />
    <MyCollecProp />
    <MyCollecProp />
    <MyCollecProp />
  </MyInnerProp>
</mytag:MyUserControl>

Of course, I'm assuming you already know how to write your collection class and naturally your data class.

Wonderful idea huh!! Look at it get implemented at SgDotNet website!

I'm not too sure whether any of you guys understood, if there's any questions, just post in the comments and I'll reply them.

w00t rocks!

No comments: