Your question is interesting, but it would be nice to actually duplicate the behavior. Could you please post all the code for the control or send it to me off list.
Dean Fiala ----------------------------- Very Practical Software, Inc. http://www.vpsw.com/links.aspx -----Original Message----- From: Todd Lucas [mailto:[EMAIL PROTECTED] Sent: Saturday, May 08, 2004 8:05 PM To: [EMAIL PROTECTED] Subject: [AspNetAnyQuestionIsOk] WebControl Persistance Problem with CollectionBase Hello everyone! I'm having a problem with a WebControl that I'm designing for a Menu. I've been at it for about 3 weeks now, and can't seem to get around this problem. So I'm hoping that someone can help me ... My environment: VS 2003 v7.1.3088, Win2K v5.0.2195 SP3, IE6 v6.0.2800.1106 browser. I have a class (C3Menu) derived from WebControl, with a property (MenuItems) that is a collection of menu items. The collection property is defined as a class which inherits from CollectionBase. I also have a Designer associated to the C3Menu class which allows design-time support. See the code below for more details. The control is generating properly - the menu items are being persisted to the HTML view, and the control is rendering ok in both design view and at run-time. An ellipse button appears next to the MenuItems collection, which allows me to add / remove items from the collection via the standard collection editor - everything seems normal! The problem is when I use the following sequence of events: 1) I run my test application to bring the page up in IE6, everything looks ok. 2) I close the page to return back to the VS editor. 3) I single-click my control to display the properties in the property browser. 4) I click the ellipses button to edit the menuitems collection. 5) I click Add to add a new item to the collection - I see the item added in the left pane of the collection editor. 6) I click Ok to return to VS view. 7) The item(s) I just added do not persist to the HTML view, nor to the design view! It gets better! If I click to the HTML view and back to the Design view, the design view gets updated with the new items - but if I click back to the HTML view, the items are still not persisted! If I go through the above sequence of events again (immediately after the HTML/Design view switch), I still see my new items I added - and when I add another item (via collection editor) and select Ok to return to design view it updates it with ALL my new items I added and the items are persisted in the HTML view! It gets even weirder! I can go through the above sequence of events, but if I select another web control between steps 2 and 3 (a Label for instance) everything is persisted correctly. I originally wrote my own custom collection editor and was having the same problem, so I decided just to utilize the standard collectioneditor - with the same results. After all of the reading I've done, I'm thinking it has something to do with a TypeConverter but am not for sure. I added the type converter on the MenuItem (collection item) definition, but it did not seem to help. Any ideas? I would be happy to send the code for anyone to look at, as this is more of a learning experience for me than anything. This is my first design-time control writing attempt - any help would be appreciated. Thanks, Todd Lucas email: Todd.Lucas -at- cox.net Code snippets: ---------------------------------------------------------------------- ------ - C3Menu.vb - C3Menu Class Definition Imports System.ComponentModel Imports System.ComponentModel.Design Imports System.Web.UI Imports System.Collections.Specialized Imports System.Web.UI.WebControls.CommandEventArgs Imports System.Web.UI.WebControls Imports System.Drawing Imports System.Drawing.Design Namespace C3WebControls <DefaultProperty("MenuItems"), DefaultEvent("ItemClick"), _ Description("Server Control - Menu Definition."), _ ParseChildren(True), PersistChildren(False), _ Designer(GetType(C3WebControls.C3Menu_Designer)), _ ToolboxData("<{0}:C3Menu runat=server></{0}:C3Menu>")> _ Public Class C3Menu : Inherits System.Web.UI.WebControls.WebControl ... ' Menu items storage: Dim _menuitems As New C3MenuItems ... <Bindable(False), Category("Menu Properties"), NotifyParentProperty (True), _ DesignerSerializationVisibility (DesignerSerializationVisibility.Content), _ PersistenceMode(PersistenceMode.InnerProperty), _ Editor(GetType(C3WebControls.C3MenuItem_CollectionEditor), GetType(UITypeEditor)), _ Description("Collection of Menu Items this object will display.")> _ Public ReadOnly Property [MenuItems]() As C3MenuItems Get Return _menuitems End Get 'This property has no SET value! End Property ... ---------------------------------------------------------------------- ------ - C3MenuItems.vb - C3MenuItems Class Definition Imports System.Web.UI Imports System.Globalization Imports System.ComponentModel Imports System.ComponentModel.Design.Serialization Namespace C3WebControls ' Menu Item Collection Class: <Description("Menu Item Collection Definition.")> _ Public Class C3MenuItems : Inherits CollectionBase Default Public Property Item(ByVal index As Integer) As C3MenuItem Get Return DirectCast(MyBase.List.Item(index), C3MenuItem) End Get Set(ByVal value As C3MenuItem) MyBase.List.Item(index) = value End Set End Property Public Overridable Function Add(ByVal value As C3MenuItem) As Integer MyBase.List.Add(value) End Function Public Overloads Sub Remove(ByVal Index As Integer) ' ensure that the object exists in the collection. Dim mnuitm As C3MenuItem mnuitm = CType(Me.InnerList.Item(Index), C3MenuItem) ' remove object to the collection (by index). If Not mnuitm Is Nothing Then Me.InnerList.Remove(mnuitm) End Sub End Class End Namespace ---------------------------------------------------------------------- ------ - C3MenuItem.vb - C3MenuItem Class Definition Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.WebControls.CommandEventArgs Imports System.Drawing.Design Imports System.Drawing Imports System.Reflection Imports System.Globalization Imports System.ComponentModel Imports System.ComponentModel.Design.Serialization Namespace C3WebControls <DefaultProperty("Text"), _ TypeConverter(GetType(C3MenuItem_TypeConverter)), _ Description("Menu Item Properties Definition.")> _ Public Class C3MenuItem <NonSerialized()> _ Public pOwningMenu As C3Menu ' MenuItem property storage: Dim _align As String = "" Dim _closeonclick As Boolean = True Dim _color3dhigh As Color = ColorTranslator.FromHtml("") ... all properties are 1 of the above type - string, boolean, color. ... standard Property Get / Set ... Public Function Clone() As C3MenuItem Dim BinFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Dim memStream As New System.IO.MemoryStream ' Serialize the memorystream object to this instance of the object. BinFormatter.AssemblyFormat = Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple BinFormatter.Serialize(memStream, Me) memStream.Position = 0 ' DeSerialize the memorystream object. Dim newItm As New C3MenuItem newItm = CType(BinFormatter.Deserialize(memStream), C3MenuItem) ' return the clone. Return newItm End Function End Class Friend Class C3MenuItem_TypeConverter : Inherits TypeConverter Public Overloads Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean If sourceType Is GetType(InstanceDescriptor) Then Return True End If Return MyBase.CanConvertFrom(context, sourceType) End Function Public Overloads Overrides Function CanConvertTo(ByVal context As ITypeDescriptorContext, ByVal destType As Type) As Boolean If destType Is GetType(InstanceDescriptor) Then Return True End If Return MyBase.CanConvertTo(context, destType) End Function Public Overloads Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object, ByVal destType As Type) As Object If destType Is GetType(InstanceDescriptor) Then Dim ci As ConstructorInfo = GetType(C3MenuItem).GetConstructor(System.Type.EmptyTypes) Return New InstanceDescriptor(ci, Nothing, False) End If Return MyBase.ConvertTo(context, culture, value, destType) End Function End Class ---------------------------------------------------------------------- ------ - C3Menu_Designer.vb - C3Menu Designer Definition Imports System.Web.UI.Design Imports System.ComponentModel.Design Imports System.ComponentModel Imports System.Drawing.Design Namespace C3WebControls ' Designer class for the C3Menu control. Public Class C3Menu_Designer : Inherits ControlDesigner ' Use PreFilterProperties to remove properties from the designer view. Protected Overloads Overrides Sub PreFilterProperties(ByVal Properties As System.Collections.IDictionary) ' Invoke base class method: MyBase.PreFilterProperties(Properties) ' Remove specified properties from design view: Properties.Remove("AccessKey") Properties.Remove("Visible") End Sub ' Returns the html to use to represent an empty control at design time. Protected Overrides Function GetEmptyDesignTimeHtml() As String Dim sTxt As String = "No Menu Items Defined" Return CreatePlaceHolderDesignTimeHtml(sTxt) End Function ' Returns the html which represents the control at design time. Public Overrides Function GetDesignTimeHtml() As String ' Invoke base class method. Dim html As String = MyBase.GetDesignTimeHtml() ' Set reference to current control instance. Dim mnu As C3Menu = DirectCast(Component, C3Menu) Dim tblstyle As String tblstyle &= "width:" & mnu.Width.ToString & "; " tblstyle &= "height:" & mnu.Height.ToString & "; " ' If no items defined then display this. If mnu.MenuItems.Count = 0 Then Return html Dim itm As C3MenuItem Dim styl As C3MenuStyle Dim itmstyle As String ' set reference to menustyle object. styl = DirectCast(mnu.FindControl(mnu.MenuStyle), C3MenuStyle) ' if style was assigned, then use style font. If Not styl Is Nothing Then If Len(styl.FontFamily) > 0 Then tblstyle &= "font-family:" & styl.FontFamily & "; " If Len(styl.FontSize) > 0 Then tblstyle &= "font-size:" & styl.FontSize & "; " If Len(styl.FontWeight) > 0 Then tblstyle &= "font-weight:" & styl.FontWeight & "; " End If ' Build a table for menu items. html = "" html &= "<table style=" & Chr(34) & tblstyle & Chr(34) & ">" & vbCrLf If LCase(mnu.Orientation) = "horizontal" Then html &= "<tr>" ' Display menu as defined. For Each itm In mnu.MenuItems If Not LCase(mnu.Orientation) = "horizontal" Then html &= "<tr>" & vbCrLf html &= "<td>" & itm.Text & "</td>" & vbCrLf If Not LCase(mnu.Orientation) = "horizontal" Then html &= "</tr>" & vbCrLf Next If LCase(mnu.Orientation) = "horizontal" Then html &= "</tr>" html &= "</table>" 'System.Windows.Forms.MessageBox.Show("GetDesignTimeHtml - HTML:" & vbCrLf & vbCrLf & html, "C3Menu_Designer") Return html End Function End Class End Namespace ---------------------------------------------------------------------- ------ - WebForm1.aspx - WebForm HTML View <cc1:C3Menu id="C3Menu1" style="LEFT: 208px; TOP: 120px" runat="server" MenuStyle="C3MenuStyle1"> <MenuItems> <cc1:C3MenuItem Text="Item Text"></cc1:C3MenuItem> <cc1:C3MenuItem Text="Item Text"></cc1:C3MenuItem> <cc1:C3MenuItem Text="Item Text"></cc1:C3MenuItem> <cc1:C3MenuItem Text="Item Text"></cc1:C3MenuItem> <cc1:C3MenuItem Text="Last"></cc1:C3MenuItem> </MenuItems> </cc1:C3Menu> Yahoo! Groups Links ------------------------ Yahoo! Groups Sponsor ---------------------~--> Yahoo! Domains - Claim yours for only $14.70 http://us.click.yahoo.com/Z1wmxD/DREIAA/yQLSAA/saFolB/TM ---------------------------------------------------------------------~-> Yahoo! Groups Links <*> To visit your group on the web, go to: http://groups.yahoo.com/group/AspNetAnyQuestionIsOk/ <*> To unsubscribe from this group, send an email to: [EMAIL PROTECTED] <*> Your use of Yahoo! Groups is subject to: http://docs.yahoo.com/info/terms/
