Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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.

Posted (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 by PlausiblyDamp
Posted (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 by PlausiblyDamp

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...