Custom Composite Server Control Children not visible to the designer
-
I'm developing a TabStrip control and am having a bit of an issue with the designer and child controls. Below is the relevant code in regards to the problem (I can provide more if needed).
\[ParseChildren(true), PersistChildren(false)\] \[ToolboxData("<{0}:TabStrip runat=server></{0}:TabStrip>")\] public class TabStrip : CompositeControl, IPostBackEventHandler { private Tab mySelectedTab; private TabCollection myTabs; public TabStrip() { this.myTabs = new TabCollection(this); } \[MergableProperty(false)\] public Tab SelectedTab { get { foreach (Tab tab in this.Tabs) if (tab.IsSelected) return tab; return null; } set { value.IsSelected = true; } } \[PersistenceMode(PersistenceMode.InnerProperty), NotifyParentProperty(true)\] \[MergableProperty(false)\] public TabCollection Tabs { get { return myTabs; } } }
When I add tabs to the
Tabs
property on a page using the property grid's collection editor the tabs are listed in the collection editor by ID and can also be selected from a drop-down list from the property grid for theSelectedTab
property. This is good and is exactly how I want the control to behave in the designer. The problem is, when the page is closed and reopened in the designer, the markup is still there, but when editing the child tabs in the collection editor they are listed by there class name rather than ID, changes made in the collection editor are not persisted, and they are no longer listed in the drop-down for theSelectedTab
property. This is no good. TheTabCollection
class implements theIList
interface and all theTab
's public properties have theNotifyParentPropertyAttribute
set to true. Please advise as to what may be missing for the designer to be aware of the child controls when the page containing the control is reopened. Thank you. -
I'm developing a TabStrip control and am having a bit of an issue with the designer and child controls. Below is the relevant code in regards to the problem (I can provide more if needed).
\[ParseChildren(true), PersistChildren(false)\] \[ToolboxData("<{0}:TabStrip runat=server></{0}:TabStrip>")\] public class TabStrip : CompositeControl, IPostBackEventHandler { private Tab mySelectedTab; private TabCollection myTabs; public TabStrip() { this.myTabs = new TabCollection(this); } \[MergableProperty(false)\] public Tab SelectedTab { get { foreach (Tab tab in this.Tabs) if (tab.IsSelected) return tab; return null; } set { value.IsSelected = true; } } \[PersistenceMode(PersistenceMode.InnerProperty), NotifyParentProperty(true)\] \[MergableProperty(false)\] public TabCollection Tabs { get { return myTabs; } } }
When I add tabs to the
Tabs
property on a page using the property grid's collection editor the tabs are listed in the collection editor by ID and can also be selected from a drop-down list from the property grid for theSelectedTab
property. This is good and is exactly how I want the control to behave in the designer. The problem is, when the page is closed and reopened in the designer, the markup is still there, but when editing the child tabs in the collection editor they are listed by there class name rather than ID, changes made in the collection editor are not persisted, and they are no longer listed in the drop-down for theSelectedTab
property. This is no good. TheTabCollection
class implements theIList
interface and all theTab
's public properties have theNotifyParentPropertyAttribute
set to true. Please advise as to what may be missing for the designer to be aware of the child controls when the page containing the control is reopened. Thank you.The designer is evil. Do not use it.
Christian Graus Driven to the arms of OSX by Vista. Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
-
The designer is evil. Do not use it.
Christian Graus Driven to the arms of OSX by Vista. Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.
But I like the designer. Besides, this is a TabStrip that I intend to share. There must be something I'm missing that the CollectionEditor does to make the designer aware of the controls it added that I could implement in the control, but I have no idea what.
-
I'm developing a TabStrip control and am having a bit of an issue with the designer and child controls. Below is the relevant code in regards to the problem (I can provide more if needed).
\[ParseChildren(true), PersistChildren(false)\] \[ToolboxData("<{0}:TabStrip runat=server></{0}:TabStrip>")\] public class TabStrip : CompositeControl, IPostBackEventHandler { private Tab mySelectedTab; private TabCollection myTabs; public TabStrip() { this.myTabs = new TabCollection(this); } \[MergableProperty(false)\] public Tab SelectedTab { get { foreach (Tab tab in this.Tabs) if (tab.IsSelected) return tab; return null; } set { value.IsSelected = true; } } \[PersistenceMode(PersistenceMode.InnerProperty), NotifyParentProperty(true)\] \[MergableProperty(false)\] public TabCollection Tabs { get { return myTabs; } } }
When I add tabs to the
Tabs
property on a page using the property grid's collection editor the tabs are listed in the collection editor by ID and can also be selected from a drop-down list from the property grid for theSelectedTab
property. This is good and is exactly how I want the control to behave in the designer. The problem is, when the page is closed and reopened in the designer, the markup is still there, but when editing the child tabs in the collection editor they are listed by there class name rather than ID, changes made in the collection editor are not persisted, and they are no longer listed in the drop-down for theSelectedTab
property. This is no good. TheTabCollection
class implements theIList
interface and all theTab
's public properties have theNotifyParentPropertyAttribute
set to true. Please advise as to what may be missing for the designer to be aware of the child controls when the page containing the control is reopened. Thank you.Getting collection editors work correctly with designer is not trivial. Please take a look at my article and source code associated : XP Style Navigation Bar Server Control with collection property and embedded resources[^].
Navaneeth How to use google | Ask smart questions
-
Getting collection editors work correctly with designer is not trivial. Please take a look at my article and source code associated : XP Style Navigation Bar Server Control with collection property and embedded resources[^].
Navaneeth How to use google | Ask smart questions
Thanks, I added the
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
attribute and that fixed the changes issues (It was there before but I removed it thinking it rendundant to thePersistanceMode
, oops). I ended up making a custom UITypeEditor to list the child tabs for theSelectedTab
property. That brought to my attention a flaw to the logic of setting that property in the designer since it doesn't know how to persist a control value by it's ID. So I ended up setting the[Browsable(false)]
attribute on theSelectedTab
property and implementing aSelectedTabID
property and using the custom UITypeEditor for that property. It is a bit of a workaroung but all is well now. I know I've seen a TypeConverter or something out there that can be used to list control ids of a certain type, but can't recall how, nor do I think it would work since the designer is still unaware of the child controls unless added with the CollectionEditor. Thanks for pointing me to your article, looks like a cool control. I'll have to look closer even though I have already implemented a solution. -
Thanks, I added the
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
attribute and that fixed the changes issues (It was there before but I removed it thinking it rendundant to thePersistanceMode
, oops). I ended up making a custom UITypeEditor to list the child tabs for theSelectedTab
property. That brought to my attention a flaw to the logic of setting that property in the designer since it doesn't know how to persist a control value by it's ID. So I ended up setting the[Browsable(false)]
attribute on theSelectedTab
property and implementing aSelectedTabID
property and using the custom UITypeEditor for that property. It is a bit of a workaroung but all is well now. I know I've seen a TypeConverter or something out there that can be used to list control ids of a certain type, but can't recall how, nor do I think it would work since the designer is still unaware of the child controls unless added with the CollectionEditor. Thanks for pointing me to your article, looks like a cool control. I'll have to look closer even though I have already implemented a solution.Good. Let me know if you find any flaws in the code.
Navaneeth How to use google | Ask smart questions
-
Good. Let me know if you find any flaws in the code.
Navaneeth How to use google | Ask smart questions
Will do.