In an attempt to create a custom data source that is supposed to be used in ASP.NET, I've created a custom data source class, a custom editor and a custom serializable class.
What I fail to understand is why it doesn't work... even though I probably have more attributes than required (I've been browsing and trying things for hours), from what I understand the PersistenceMode(PersistenceMode.InnerProperty)
should have done the trick... Also, it seems to me like my code is similar to Why can't I declare sub-elements (properties) of a UserControl in a WebForm? .
The code works as follows:
[ParseChildren(true)]
[PersistChildren(true)]
public class MyDataSource : DataSourceControl
{
// [much more irrelevant code...]
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[MergableProperty(false)]
[TypeConverter(typeof(ExpandableObjectConverter))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(Editors.ResultRequestEditor), typeof(System.Drawing.Design.UITypeEditor))]
public ResultRequest Request { get; set; }
}
[Serializable]
[PersistChildren(true)]
[TypeConverter(typeof(ExpandableObjectConverter))]
[ParseChildren(true)]
public class ResultRequest
{
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public string ColumnName { get; set; }
[Browsable(true)]
[EditorBrowsable(EditorBrowsableState.Always)]
public Type ColumnType { get; set; }
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Always)]
public object[] ResultTypeParameters { get; set; }
}
The custom editor seems to work: after using it, the properties in VS are updated correctly.
However, after updating something the information is not persisted in the ASPX file:
<cc1:MyDataSource ID="SearchDataSource1" runat="server" ProviderID="MyProvider1" />
What I expected was some serialization within the data source, e.g.:
<cc1:MyDataSource ID="SearchDataSource1" runat="server" ProviderID="MyProvider1">
<Request>
// blah
</Request>
</cc1:MyDataSource>
Can someone please explain why this doesn't work?
Please take a look at my sample it's less complex so it would be easier to understand:
First parent control (in your case this would be DataSource):
[ToolboxData("<{0}:TabContainer runat=server></{0}:TabContainer>")]
[ParseChildren(ChildrenAsProperties = false)]
[PersistChildren(true)]
public class TabContainer : Panel, INamingContainer
{
#region private properties
List<TabItem> tabs = new List<TabItem>();
#endregion
[Bindable(true)]
public event EventHandler TabClick;
[Browsable(true)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public List<TabItem> Tabs
{
get { return this.tabs; }
}
}
Take notice I have set ChildrenAsProperties to false. And here is child definition, TabItem:
public class TabItem : Panel, IPostBackEventHandler
{
String clientClick = String.Empty;
public event EventHandler Click;
[Bindable(true)]
[Category("Appearance")]
public string Text
{
get
{
if (ViewState["Text"] == null)
{
ViewState["Text"] = "";
}
return (string)ViewState["Text"];
}
set
{
ViewState["Text"] = value;
}
}
}
Now inside designer I can declare TabContainer like this:
<cc1:TabContainer ID="TabContainer1" runat="server"
</cc1:TabContainer>
And finally add child controls that preserve state:
<cc1:TabContainer ID="TabContainer1" runat="server"
OnTabClick="TabContainer_TabClick">
<Tabs>
<cc1:TabItem ID="Tab1" Text="Hello" runat="server" />
<cc1:TabItem ID="Tab2" Text="World" runat="server" />
</Tabs>
</cc1:TabContainer>
Best regards!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With