B
Bill Anderson
Hi,
I am trying to accomplish the following.
Here is what I want to do:
1. Drop a custom business object component onto the
design surface and have it show up in the area below the
designer grid in VisStudio (like a dataadapter or dataset
does).
2. Drag a textbox webcontrol and change a custom
datasource property to the component from step 1. The
property grid will display a drop down of available
datasources (i want the textbox to work like a dropdown
control).
3. Based on the datasource chosen, change a
DataTextField property to a valid property of the
component. The property grid will show a drop down of
available Public Properties (fields) from the component
selected (basically, binding values to the textbox work
like the dropdown box does when binding to a dataset).
4. The Datasource and DataTextField values chosen will
persist as attributes in HTML on the custom component.
5. The componet is a basic business object. It does not
implement IEnumerable or IListsource (it does implement
IComponent). It just exposes public properties.
I have all of this working fine if the custom component
is of type Collection. But I don't want a Collection,
just the ability to bind to Public Properties of a basic
class.
I think have taken care of most of the items as follow,
but I am stuck on #5:
1. Implement IComponent on the business class.
2. Created custom control derived from Textbox webcontrol.
3. Created custom Designer that implements
IDatasourceprovider, and attach to custom textbox control.
4. Put designerserialization attribute of visible on
properties of custom textbox control.
5. Can't get to work unless the component Implements
IEnumerable, and then it only shows up in the datasource
drop down. I can never get the properties to list out
unless i have a stongly typed collection of busines
objects.
here is some sample code(i shortened syntax for brevity):
<Designer(Gettype(MyCustomDesigner)), otherattributes...>
_
Public Class MyTextBox : Inherits from TextBox
Private mDataSource as string = ""
Private mDataTextField as string = ""
<otherattributes, designerserialation...(visible)> _
Public Property DataSource as string
get
return mDataSource
end get
set(Value as string)
mDataSource = Value
end set
end property
'Repeat for the DataTextField Property
End Class
Public Class MyAddressObject : Implements IComponent,
IEnumberable 'IEnumerable causes this to become a valid
datasource in the datasource drop down. Should I use
something else?.
Private mStreet as string
Private mCity as string
Private mSite as ISite
'etc.
'Implement IComponet stuff here
'If IEnumberable is needed, how to implement
GetEnumerator?
Public Property Street as string
get
return mStreet
end get
set(Value as string)
mStreet = Value
end set
end property
'Implement the rest of the properties
End Class
Public Class WebDataBoundDesigner : Inherits
ControlDesigner
Implements IDataSourceProvider
Public Property DataTextField() As String
Get
Return CType(Me.Component,
MyTextBox).DataTextField
End Get
Set(ByVal Value As String)
CType(Me.Component, MyTextBox).DataTextField
= Value
End Set
End Property
Public Property DataSource() As String
Get
Return CType(Me.Component,
MyTextBox).DataSource
End Get
Set(ByVal Value As String)
CType(Me.Component, MyTextBox).DataSource =
Value
OnBindingsCollectionChanged("DataSource")
End Set
End Property
Public Function GetResolvedSelectedDataSource() As
System.Collections.IEnumerable Implements
System.Web.UI.Design.IDataSourceProvider.GetResolvedSelect
edDataSource
If Me.DataSource.Length > 0 Then
Return DesignTimeData.GetSelectedDataSource
(Me.Component, Me.DataSource, Me.DataTextField)
End If
Return Nothing
End Function
Public Function GetSelectedDataSource() As Object
Implements
System.Web.UI.Design.IDataSourceProvider.GetSelectedDataSo
urce
If Me.DataSource.Length > 0 Then
Return DesignTimeData.GetSelectedDataSource
(Me.Component, Me.DataSource)
End If
Return Nothing
End Function
Protected Overrides Sub PreFilterProperties(ByVal
properties As System.Collections.IDictionary)
MyBase.PreFilterProperties(properties)
Dim prop As PropertyDescriptor
prop = CType(properties("DataSource"),
PropertyDescriptor)
prop = TypeDescriptor.CreateProperty
(Me.GetType, "DataSource", GetType(String), New Attribute
() {New TypeConverterAttribute(GetType
(DataSourceConverter))})
properties("DataSource") = prop
prop = CType(properties("DataTextField"),
PropertyDescriptor)
prop = TypeDescriptor.CreateProperty
(Me.GetType, "DataTextField", GetType(String), New
Attribute() {New TypeConverterAttribute(GetType
(DataFieldConverter))})
properties("DataTextField") = prop
End Sub
End Class
I am trying to accomplish the following.
Here is what I want to do:
1. Drop a custom business object component onto the
design surface and have it show up in the area below the
designer grid in VisStudio (like a dataadapter or dataset
does).
2. Drag a textbox webcontrol and change a custom
datasource property to the component from step 1. The
property grid will display a drop down of available
datasources (i want the textbox to work like a dropdown
control).
3. Based on the datasource chosen, change a
DataTextField property to a valid property of the
component. The property grid will show a drop down of
available Public Properties (fields) from the component
selected (basically, binding values to the textbox work
like the dropdown box does when binding to a dataset).
4. The Datasource and DataTextField values chosen will
persist as attributes in HTML on the custom component.
5. The componet is a basic business object. It does not
implement IEnumerable or IListsource (it does implement
IComponent). It just exposes public properties.
I have all of this working fine if the custom component
is of type Collection. But I don't want a Collection,
just the ability to bind to Public Properties of a basic
class.
I think have taken care of most of the items as follow,
but I am stuck on #5:
1. Implement IComponent on the business class.
2. Created custom control derived from Textbox webcontrol.
3. Created custom Designer that implements
IDatasourceprovider, and attach to custom textbox control.
4. Put designerserialization attribute of visible on
properties of custom textbox control.
5. Can't get to work unless the component Implements
IEnumerable, and then it only shows up in the datasource
drop down. I can never get the properties to list out
unless i have a stongly typed collection of busines
objects.
here is some sample code(i shortened syntax for brevity):
<Designer(Gettype(MyCustomDesigner)), otherattributes...>
_
Public Class MyTextBox : Inherits from TextBox
Private mDataSource as string = ""
Private mDataTextField as string = ""
<otherattributes, designerserialation...(visible)> _
Public Property DataSource as string
get
return mDataSource
end get
set(Value as string)
mDataSource = Value
end set
end property
'Repeat for the DataTextField Property
End Class
Public Class MyAddressObject : Implements IComponent,
IEnumberable 'IEnumerable causes this to become a valid
datasource in the datasource drop down. Should I use
something else?.
Private mStreet as string
Private mCity as string
Private mSite as ISite
'etc.
'Implement IComponet stuff here
'If IEnumberable is needed, how to implement
GetEnumerator?
Public Property Street as string
get
return mStreet
end get
set(Value as string)
mStreet = Value
end set
end property
'Implement the rest of the properties
End Class
Public Class WebDataBoundDesigner : Inherits
ControlDesigner
Implements IDataSourceProvider
Public Property DataTextField() As String
Get
Return CType(Me.Component,
MyTextBox).DataTextField
End Get
Set(ByVal Value As String)
CType(Me.Component, MyTextBox).DataTextField
= Value
End Set
End Property
Public Property DataSource() As String
Get
Return CType(Me.Component,
MyTextBox).DataSource
End Get
Set(ByVal Value As String)
CType(Me.Component, MyTextBox).DataSource =
Value
OnBindingsCollectionChanged("DataSource")
End Set
End Property
Public Function GetResolvedSelectedDataSource() As
System.Collections.IEnumerable Implements
System.Web.UI.Design.IDataSourceProvider.GetResolvedSelect
edDataSource
If Me.DataSource.Length > 0 Then
Return DesignTimeData.GetSelectedDataSource
(Me.Component, Me.DataSource, Me.DataTextField)
End If
Return Nothing
End Function
Public Function GetSelectedDataSource() As Object
Implements
System.Web.UI.Design.IDataSourceProvider.GetSelectedDataSo
urce
If Me.DataSource.Length > 0 Then
Return DesignTimeData.GetSelectedDataSource
(Me.Component, Me.DataSource)
End If
Return Nothing
End Function
Protected Overrides Sub PreFilterProperties(ByVal
properties As System.Collections.IDictionary)
MyBase.PreFilterProperties(properties)
Dim prop As PropertyDescriptor
prop = CType(properties("DataSource"),
PropertyDescriptor)
prop = TypeDescriptor.CreateProperty
(Me.GetType, "DataSource", GetType(String), New Attribute
() {New TypeConverterAttribute(GetType
(DataSourceConverter))})
properties("DataSource") = prop
prop = CType(properties("DataTextField"),
PropertyDescriptor)
prop = TypeDescriptor.CreateProperty
(Me.GetType, "DataTextField", GetType(String), New
Attribute() {New TypeConverterAttribute(GetType
(DataFieldConverter))})
properties("DataTextField") = prop
End Sub
End Class