-
What's wrong with my TypeConverter? (.NET 2.0, VB)
I am trying to get a PropertyGrid to give me a dropdown list for my custom object with a selection of items loaded from a file.
The problem is that the dropdown list is populated with the number of empty strings as I have elements loaded from the file.
The object:
Code:
Imports System.ComponentModel
<Serializable(), TypeConverter(GetType(ElementConverter))> Public Class Element
Private eName As String
Private eStd As String
Private eStdNo As String
Private eMatNo As Double
Private eEMod As Double
Private ePoisson As Double
Private eDensity As Double
Private eAlpha As Double
Private eEP As Double
Private eSF As Double
Private eDamping As Double
Public Overrides Function ToString() As String
Return eName & " " & eStd & " " & eStdNo & " " & eMatNo & " " & eEMod & " " & ePoisson & " " & eDensity & " " & eAlpha & " " & eEP & " " & eSF & " " & eDamping
End Function
Public Sub New(ByVal nName As String)
eName = nName
End Sub
Public Sub New(ByVal nName As String, ByVal nStd As String, ByVal nStdNo As String, ByVal nMatNo As Double, ByVal nEMod As Double, ByVal nPoisson As Double, ByVal nDensity As Double, ByVal nAlpha As Double, ByVal nEP As Double, ByVal nSF As Double, ByVal nDamping As Double)
eName = nName
eStd = nStd
eStdNo = nStdNo
eMatNo = nMatNo
eEMod = nEMod
ePoisson = nPoisson
eDensity = nDensity
eAlpha = nAlpha
eEP = nEP
eSF = nSF
eDamping = nDamping
End Sub
Public ReadOnly Property Name() As String
Get
Return eName
End Get
End Property
Public Property Std() As String
Get
Return eStd
End Get
Set(ByVal value As String)
eStd = value
End Set
End Property
Public Property StdNo() As String
Get
Return eStdNo
End Get
Set(ByVal value As String)
eStdNo = value
End Set
End Property
Public Property MatNo() As Double
Get
Return eMatNo
End Get
Set(ByVal value As Double)
eMatNo = value
End Set
End Property
Public Property EMod() As Double
Get
Return eEMod
End Get
Set(ByVal value As Double)
eEMod = value
End Set
End Property
Public Property Density() As Double
Get
Return eDensity
End Get
Set(ByVal value As Double)
eDensity = value
End Set
End Property
Public Property Alpha() As Double
Get
Return eAlpha
End Get
Set(ByVal value As Double)
eAlpha = value
End Set
End Property
Public Property EP() As Double
Get
Return eEP
End Get
Set(ByVal value As Double)
eEP = value
End Set
End Property
Public Property SF() As Double
Get
Return eSF
End Get
Set(ByVal value As Double)
eSF = value
End Set
End Property
Public Property Damping() As Double
Get
Return eDamping
End Get
Set(ByVal value As Double)
eDamping = value
End Set
End Property
End Class
The converter:
Code:
Imports System.ComponentModel
Public Class ElementConverter
Inherits StringConverter ' I've tried inheriting TypeConverter, ExpandableObjectConverter as well.
Public Shared ElementKeys As String()
Public Overrides Function GetStandardValuesSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
Return True
End Function
Public Overrides Function GetStandardValuesExclusive(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
Return False
End Function
Public Overloads Overrides Function GetStandardValues( _
ByVal context As ITypeDescriptorContext) _
As StandardValuesCollection
Return New StandardValuesCollection(ElementKeys)
End Function
Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
If destinationType Is GetType(String) Then
If Not value Is Nothing AndAlso value.GetType() Is GetType(Element) Then
Dim e As Element = value
Return e.ToString()
End If
Return ""
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
Public Overloads Overrides Function ConvertFrom( _
ByVal context As ITypeDescriptorContext, _
ByVal culture As Globalization.CultureInfo, _
ByVal value As Object) As Object
If (TypeOf value Is String) Then
'Try
Dim s As String = CStr(value)
Dim split As String() = s.Split(" ")
If (split.Length = 11) Then
Dim e As New Element(split(0), split(1), split(2), split(3), split(4), split(5), split(6), split(7), split(8), split(9), split(10))
Return e
End If
'Catch
'Throw New ArgumentException("Can not convert '" & CStr(value) & "' to type Element")
'End Try
End If
Return MyBase.ConvertFrom(context, culture, value)
End Function
Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
If (destinationType Is GetType(String)) Then
Return True
End If
Return MyBase.CanConvertTo(context, destinationType)
End Function
Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
If (sourceType Is GetType(String)) Then
Return True
End If
Return MyBase.CanConvertFrom(context, sourceType)
End Function
End Class
Here is where I populate the dropdown list:
Code:
Elements = New SortedList(Of String, Element)
If System.IO.File.Exists(".\mat_blin.ndb") = True Then
Dim Reader As New System.IO.StreamReader(".\mat_blin.ndb")
Dim i As Integer
While Reader.EndOfStream = False
Dim curString As String = Reader.ReadLine()
If curString.StartsWith("#") = True OrElse curString.StartsWith("NADWORK") = True Then
Continue While
Else
' # Name Std. StdNo. MatNo. E nue roh alpha Ep Sf Damping
If ElementConverter.ElementKeys Is Nothing Then
ReDim ElementConverter.ElementKeys(0)
Else
ReDim ElementConverter.ElementKeys(ElementConverter.ElementKeys.Length)
End If
Dim SplitString As String() = curString.Substring(15).Split(" ", 12, StringSplitOptions.RemoveEmptyEntries)
Dim ne As New Element(curString.Substring(0, 15).Trim(), SplitString(0), SplitString(1), SplitString(2), SplitString(3), SplitString(4), SplitString(5), SplitString(6), SplitString(7), SplitString(8), SplitString(9))
ElementConverter.ElementKeys(i) = ne.ToString()
Debug.Print(ne.ToString())
i = i + 1
Elements.Add(ne.Name, ne)
End If
End While
End If
Any ideas? I hope I've given enough information...
Thanks in advance!
-
Can't you delete the empty strings from your file before running your code?
-
The list was populating with an exact number of empty strings as I had lines in the file. In other words, it wasn't putting any of the actual lines from the file into the list at all, whether or not I'd had any blank lines or not (There were none, btw)
I found the problem, however, but I'm not quite sure how to describe what I did wrong. I was missing the code to return the string straight up, if the source type was already a string. I believe it was because the .NET propertygrid was asking it to convert from the object to a string, then converting that same string again once more before actually settling in with a final object lined up with each string in the PropertyGrid in-line editor. I think the old code was returning a blank string on the second conversion because the item was already a string, not an object of the type it was expecting.
Here are those new codes, for anybody who might run into a similar situation. Note: I renamed Element to Material and simply used the material name as the key since the original posting.
Code:
Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
If destinationType Is GetType(String) Then
If Not value Is Nothing Then
If value.GetType Is GetType(Material) Then
Dim mvalue As Material = value
If mvalue.Name = "" Then
Return "Reset (None)"
End If
Return mvalue.Name
ElseIf value.GetType Is GetType(String) Then
Return value
Else
Return "Not a material"
End If
End If
Return "Choose..."
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function
Public Overrides Function ConvertFrom( _
ByVal context As ITypeDescriptorContext, _
ByVal culture As Globalization.CultureInfo, _
ByVal value As Object) As Object
If (TypeOf value Is String) AndAlso value.Length > 0 Then
Dim s As String = value.ToString()
If Not Layers.Materials Is Nothing Then
If Layers.Materials.ContainsKey(s) = True Then
Return Layers.Materials(s)
Else
Return New Material("")
End If
Else
Return New Material("")
End If
ElseIf TypeOf value Is String Then
Return New Material("")
ElseIf value Is Nothing Then
Return New Material("")
End If
Return MyBase.ConvertFrom(context, culture, value)
End Function
Similar Threads
-
Replies: 2
Last Post: 10-09-2006, 07:40 PM
-
By Seth Grossman [MSFT] in forum vb.announcements
Replies: 1
Last Post: 03-13-2002, 07:32 PM
-
By AutomatedQA in forum dotnet.announcements
Replies: 0
Last Post: 11-19-2001, 05:08 PM
-
Replies: 214
Last Post: 06-01-2001, 07:27 AM
-
By Tuomas Salste in forum vb.announcements
Replies: 0
Last Post: 01-24-2001, 12:22 PM
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|