|
Many controls have the need for a collection of strings that the page developer
can configure. One way to do this is to simply have a property that can get and
set a string array. With the proper metadata, ASP.net can persist this using a comma-separated
list. However, this is somewhat inflexible. For example, what happens if the data
itself has a comma in it?
The first thought might be to simply create a collection that contains individual
string items. After all, ASP.net is great at persisting collections! The problem
with this solution is that for ASP.net to process a collection item that item must
have public properties containing the necessary values. In the case of strings,
the only public property is Length, which is of course not very useful here.
The proper solution is to create a collection of custom items, each of which has
its own string property.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;
namespace ControlBuilderFaq.Samples {
[ParseChildren(true)]
[PersistChildren(false)]
public class ControlWithStrings : Control {
private MyItemCollection _items;
[PersistenceMode(PersistenceMode.InnerProperty)]
public MyItemCollection Items {
get {
if (_items == null) {
_items = new MyItemCollection();
}
return _items;
}
}
}
public class MyItem {
private string _value;
[DefaultValue("")]
public string Value {
get {
if (_value == null) {
return String.Empty;
}
return _value;
}
set {
_value = value;
}
}
}
public class MyItemCollection : List<MyItem> {
}
}
Now we can persist the control in the rather familiar format:
<%@ Page Language="C#" %>
<%@ Register TagPrefix="cbf" Namespace="ControlBuilderFaq.Samples" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<cbf:ControlWithStrings runat="server" ID="cws1">
<Items>
<cbf:MyItem Value="item 1" />
<cbf:MyItem Value="item 2" />
<cbf:MyItem Value="item 3" />
<cbf:MyItem Value="item 4" />
</Items>
</cbf:ControlWithStrings>
</div>
</form>
</body>
</html>
The same technique applies any time you want to have a collection of simple
types. The trick is to create a container that will hold the actual value you want
to have in your collection.
- Eilon
|