This is technically something you may want to do sometime, especially if you have a webcontrol that is grabbing a stash of data, doing some kind of organzing algorithm on it, and then displaying it to the page. If the webcontrol has any store of data within it (such as a list of items, etc) you may want to "bind" to that data from another control. How?
To do this, I simply created a UserControl that contains a ListBox with some predefined values in it:

I then had the user control implement both IEnumerable and IEnumerator:
public partial class WebUserControl :
System.Web.UI.UserControl, IEnumerable, IEnumerator
{
....
}From within the IEnumerator code, I enumerate the contents of the ListBox (technically I could probably just return the enumerator for the ListBox within the user control BACK to the object binding to the user control, but that's not exactly the point here, the point is implementing this so someone can generically bind to your user control.
Int32 _CurrentItem;
public object Current
{
get {
return this.ListBox1.Items[_CurrentItem];
}
}
public bool MoveNext()
{
if ((_CurrentItem + 1) < this.ListBox1.Items.Count)
{
_CurrentItem++;
return true;
}
else
return false;
}
public void Reset()
{
_CurrentItem = 0;
}Now that this is in place, I simply set the data source for some other object (in this case, another ListBox) to the user control:
protected void Page_Load(object sender, EventArgs e)
{
this.ListBox1.DataSource = this.WebUserControl1;
this.ListBox1.DataBind();
return;
}
The result is two listboxes on the page, one inside my user control, with the same content:

Now, as an added twist, how about doing it declaratively? Well, we simply implement IDataSource:
public partial class WebUserControl :
System.Web.UI.UserControl, IEnumerable, IEnumerator, IDataSource
{
...
}
...and now return a DataSourceView object from our class:
public class MyDataSourceView : DataSourceView
{
public MyDataSourceView(IDataSource owner, string name) : base(owner, name)
{
}
public IEnumerable EnumerableObject;
protected override IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
{
return EnumerableObject;
}
}
public DataSourceView GetView(string viewName)
{
MyDataSourceView dv = new MyDataSourceView(this, "Default");
dv.EnumerableObject = this;
return dv;
}
public ICollection GetViewNames()
{
ArrayList al = new ArrayList();
al.Add("default");
return (ICollection)al;
}Most of the meat of the DataSourceView class is unnecessary in this example, so generic strings are past, etc. The result is the same, a fully databound object - but this time it can be done declaratively.
Recommended reading:
