scali Posted May 10, 2005 Posted May 10, 2005 Hello all, I need help serializing a collection that is a property coming from the Iextenderprovider. The canextend is set to textboxes. I have it working when adding/removing components to the collection when the parent component(the extender) calls the collection editor. However, when I try to add a collection through Iextenderprovider with the set/get methods I am able to call the collection editor and add a sub component but when I recall the collection editor the components that I added are no longer there. I've searched for a few days trying to located a single instance in ether c# or vb.net where a collection is utilized in this way but havent had any luck. I'd post the code but its just a bit to big after editing it down twice. If there is a section that I need to post please let me know. Quote
scali Posted May 10, 2005 Author Posted May 10, 2005 (edited) Class 1 **Note Heavily modified into a component from the code posted by Divil's Rich Design Time Control. Option Strict On Option Explicit On Imports System.Data.OleDb Imports System.Data.SqlClient Imports System.ComponentModel Imports System.ComponentModel.Design Imports System.Windows.Forms.Design <Designer("CollectionControlDesigner"), _ ProvideProperty("FieldValue", GetType(Control)), _ ProvideProperty("Clm", GetType(Control))> _ Public Class DataExtender Inherits System.ComponentModel.Component Implements IExtenderProvider Private _Columns As DataExtenderCollection #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call _Columns = New DataExtenderCollection(Me) End Sub 'UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub #End Region #Region "Extender/Hashtable " Public Function CanExtend(ByVal extendee As Object) As Boolean _ Implements IExtenderProvider.CanExtend If TypeOf extendee Is TextBox Then Return True Else Return False End If End Function ' this hashtable holds property values for individual controls Public htProvidedProperties As New Hashtable Public Function GetAddControl(ByVal ctrl As Control) As DataExtenderProperties If htProvidedProperties.Contains(ctrl) Then Return DirectCast(htProvidedProperties(ctrl), DataExtenderProperties) Else ' add an element to the hashtable Dim ProvidedProperties As New DataExtenderProperties htProvidedProperties.Add(ctrl, ProvidedProperties) Return ProvidedProperties End If End Function #End Region ' Extender/Hastable 'working content <Browsable(True), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _ Public ReadOnly Property Columns() As DataExtenderCollection Get Return _Columns End Get End Property #Region " Get/Set " 'These need to be excatly the same as the provide properties Public Class DataExtenderProperties Public FieldValue As String = String.Empty Public Clm As DataExtenderCollection Public List As ListBox End Class Public Sub SetList(ByVal ctrl As Control, ByVal Value As ListBox) Me.GetAddControl(ctrl).List = Value End Sub Public Function GetList(ByVal ctrl As Control) As ListBox If htProvidedProperties.Contains(ctrl) Then Return DirectCast(Me.htProvidedProperties(ctrl), DataExtenderProperties).List Else Return Nothing End If End Function Public Sub SetClm(ByVal ctrl As Control, ByVal Value As DataExtenderCollection) If htProvidedProperties.Contains(ctrl) Then Me.GetAddControl(ctrl).Clm = Value End If End Sub Public Function GetClm(ByVal ctrl As Control) As DataExtenderCollection If htProvidedProperties.Contains(ctrl) Then Return DirectCast(Me.htProvidedProperties(ctrl), DataExtenderProperties).Clm End If End Function Function GetFieldValue(ByVal ctrl As Control) As String If htProvidedProperties.Contains(ctrl) Then Return DirectCast(Me.htProvidedProperties(ctrl), DataExtenderProperties).FieldValue Else Return String.Empty End If End Function Sub SetFieldValue(ByVal ctrl As Control, ByVal value As String) If value = Nothing Then value = String.Empty Me.GetAddControl(ctrl).FieldValue = value End Sub #End Region 'Individual Control Extention End Class Friend Class CollectionControlDesigner Inherits ControlDesigner Private MyControl As DataExtender Public Overrides Sub Initialize(ByVal component As System.ComponentModel.IComponent) MyBase.Initialize(component) 'Record instance of control we're designing MyControl = DirectCast(component, DataExtender) 'Hook up events Dim s As ISelectionService = DirectCast(GetService(GetType(ISelectionService)), ISelectionService) Dim c As IComponentChangeService = DirectCast(GetService(GetType(IComponentChangeService)), IComponentChangeService) AddHandler c.ComponentRemoving, AddressOf OnComponentRemoving End Sub Private Sub OnComponentRemoving(ByVal sender As Object, ByVal e As ComponentEventArgs) Dim c As IComponentChangeService = DirectCast(GetService(GetType(IComponentChangeService)), IComponentChangeService) Dim button As DataExtenderColumns Dim h As IDesignerHost = DirectCast(GetService(GetType(IDesignerHost)), IDesignerHost) Dim i As Integer 'If the user is removing a button If TypeOf e.Component Is DataExtenderColumns Then button = DirectCast(e.Component, DataExtenderColumns) If MyControl.Columns.Contains(button) Then c.OnComponentChanging(MyControl, Nothing) MyControl.Columns.Remove(button) c.OnComponentChanged(MyControl, Nothing, Nothing, Nothing) Return End If End If 'If the user is removing the control itself If e.Component Is MyControl Then For i = MyControl.Columns.Count - 1 To 0 Step -1 button = MyControl.Columns(i) c.OnComponentChanging(MyControl, Nothing) MyControl.Columns.Remove(button) h.DestroyComponent(button) c.OnComponentChanged(MyControl, Nothing, Nothing, Nothing) Next End If End Sub Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) Dim s As ISelectionService = DirectCast(GetService(GetType(ISelectionService)), ISelectionService) Dim c As IComponentChangeService = DirectCast(GetService(GetType(IComponentChangeService)), IComponentChangeService) 'Unhook events RemoveHandler c.ComponentRemoving, AddressOf OnComponentRemoving MyBase.Dispose(disposing) End Sub Public Overrides ReadOnly Property AssociatedComponents() As System.Collections.ICollection Get Return MyControl.Columns End Get End Property Private Sub OnAddButton(ByVal sender As Object, ByVal e As EventArgs) Dim button As DataExtenderColumns Dim h As IDesignerHost = DirectCast(GetService(GetType(IDesignerHost)), IDesignerHost) Dim dt As DesignerTransaction Dim c As IComponentChangeService = DirectCast(getservice(GetType(IComponentChangeService)), IComponentChangeService) 'Add a new button to the collection dt = h.CreateTransaction("Add Button") button = DirectCast(h.CreateComponent(GetType(DataExtenderColumns)), DataExtenderColumns) c.OnComponentChanging(MyControl, Nothing) MyControl.Columns.Add(button) c.OnComponentChanged(MyControl, Nothing, Nothing, Nothing) dt.Commit() End Sub End Class Edited May 11, 2005 by PlausiblyDamp Quote
scali Posted May 10, 2005 Author Posted May 10, 2005 (edited) Class 2 *Note heavily based upon Divi's posted Rich Design Time Controls Option Strict On Option Explicit On Imports System.ComponentModel Imports System.ComponentModel.Design.Serialization <TypeConverter(GetType(DataExtenderConverter)), DesignTimeVisible(True), ToolboxItem(False)> _ Public Class DataExtenderColumns Inherits Component Private _ColumnName As String Friend Control As DataExtender = Nothing Public Property ColumnName() As String Get Return Me._ColumnName End Get Set(ByVal Value As String) Me._ColumnName = Value End Set End Property End Class Friend Class DataExtenderConverter Inherits TypeConverter 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 System.Globalization.CultureInfo, ByVal value As Object, ByVal destType As Type) As Object If destType Is GetType(InstanceDescriptor) Then Dim ci As System.Reflection.ConstructorInfo = GetType(DataExtenderColumns).GetConstructor(System.Type.EmptyTypes) Return New InstanceDescriptor(ci, Nothing, False) End If Return MyBase.ConvertTo(context, culture, value, destType) End Function End Class Public Class DataExtenderCollection Inherits CollectionBase Private Control As DataExtender Friend Sub New(ByVal Control As DataExtender) Me.Control = Control End Sub Default Public ReadOnly Property Item(ByVal Index As Integer) As DataExtenderColumns Get Return DirectCast(List(Index), DataExtenderColumns) End Get End Property Public Function Contains(ByVal DC As DataExtenderColumns) As Boolean Return List.Contains(DC) End Function Public Function Add(ByVal DC As DataExtenderColumns) As Integer Dim i As Integer i = List.Add(DC) DC.Control = Control Return i End Function Public Sub Remove(ByVal DC As DataExtenderColumns) List.Remove(DC) DC.Control = Nothing End Sub End Class Edited May 11, 2005 by PlausiblyDamp Quote
scali Posted May 12, 2005 Author Posted May 12, 2005 Maybe I was to vague. I'd like to extend to a textbox the ability to hold a collection of values. Is this possible. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.