pamsauto
asked on
Need help understanding how to use IEnumable in custom class
I need help understanding how to use a custom class I have so I can bind it to a datagridview and allow the user to click a header to sort the data.
The first code chuck is the existing class.
I have a windows form with a DataGridView on it that is bound to the object. I then call this from from another form. The datagridview form code is here.
Public Sub New(ByVal rtqRates() As RateQuoteType, ByVal frmTitle As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
DataGridView1.DataSource = rtqRates
Me.Text = frmTitle
End Sub
The second chunk of code is what I believe I need to incorborate into the class, but am really lost on how to structure this, where it goes in the class, and how to make the datagrid view use the functionality. This code does have a few bugs in it I believe.
Thanks for any help in advance!
The first code chuck is the existing class.
I have a windows form with a DataGridView on it that is bound to the object. I then call this from from another form. The datagridview form code is here.
Public Sub New(ByVal rtqRates() As RateQuoteType, ByVal frmTitle As String)
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
DataGridView1.DataSource = rtqRates
Me.Text = frmTitle
End Sub
The second chunk of code is what I believe I need to incorborate into the class, but am really lost on how to structure this, where it goes in the class, and how to make the datagrid view use the functionality. This code does have a few bugs in it I believe.
Thanks for any help in advance!
Imports Microsoft.VisualBasic
Imports System.Data
Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Reflection
Public Class RateQuoteType
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Protected _Rate As Decimal
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Protected _DayInTransitMin As Integer
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Protected _DayInTransitMax As Integer
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Protected _Name As String
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Protected _ServiceDescription As String
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Protected _Surcharges As String
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Protected _Description As String
<EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)> Protected _RateBasedOnHistory As Boolean = False
''' <summary>
''' RateQuoteType is an object to hold a quoted rate for shipping a product(s) to a destination
''' Use the rate quoting classes to fill this type
''' </summary>
''' <param name="Rate">The rate to use in calculations</param>
''' <param name="DaysInTransitMin">If provided by the rating engine the shortest days until the product will be delivered, do not include time spent prepping the shipment or waiting for end terminal delivery to the customer</param>
''' <param name="DaysInTransitMax">If provided by the rating engine the maximium days until the product will be delivered, do not include time spent prepping the shipment or waiting for end terminal delivery to the customer</param>
''' <param name="Name">The name of the Service - Usually like UPS, Speedee, Etc</param>
''' <param name="ServiceDescription">Usually the description of the service - examples ; Next Day Air ; Ground </param>
''' <param name="Surcharges">A text description of surcharges that the carrier may apply - examples ; COD add $10.00 ; Residential add $10.00</param>
''' <param name="Description">Another field to add more text for the descrion to the user - this is the lowest priority in displaying</param>
''' <param name="RateBasedOnShipmentHistory">If this quote was generated with some type of weight or dimension history set to true</param>
''' <remarks></remarks>
Public Sub New(ByVal Rate As Decimal, ByVal DaysInTransitMin As Integer, ByVal DaysInTransitMax As Integer, ByVal Name As String, ByVal ServiceDescription As String, ByVal Surcharges As String, ByVal Description As String, ByVal RateBasedOnShipmentHistory As Boolean)
Me._Rate = Rate
Me._DayInTransitMin = DaysInTransitMin
Me._DayInTransitMax = DaysInTransitMax
Me._Name = Name
Me._ServiceDescription = ServiceDescription
Me._Surcharges = Surcharges
Me._Description = Description
Me._RateBasedOnHistory = RateBasedOnShipmentHistory
End Sub
''' <summary>
''' This is the cost of the rate quote for the delivery method
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property Rate As Decimal
Get
Return _Rate
End Get
Set(ByVal value As Decimal)
_Rate = value
End Set
End Property
''' <summary>
''' This is the top level Name of the Delivery Method
''' There are three levels total
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property Name As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
''' <summary>
''' This is the second level Name of th Delivery Method
''' There are three levels total
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property ServiceDescription As String
Get
Return _ServiceDescription
End Get
Set(ByVal value As String)
_ServiceDescription = value
End Set
End Property
''' <summary>
''' This is a string of what surcharges the user needs
''' to be aware of for this rate quote
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property Surcharges As String
Get
Return _Surcharges
End Get
Set(ByVal value As String)
_Surcharges = value
End Set
End Property
''' <summary>
''' This is the third level Name of th Delivery Method
''' There are three levels total
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property Description As String
Get
Return _Description
End Get
Set(ByVal value As String)
_Description = value
End Set
End Property
''' <summary>
''' The Mininium Full Business Days it will take to get the product to the customer after it is shipped
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property DaysInTransitMin As Integer
Get
Return _DayInTransitMin
End Get
Set(ByVal value As Integer)
_DayInTransitMin = value
End Set
End Property
''' <summary>
''' The Maximium Full Business Days it will take to get the product to the customer after it is shipped
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property DaysInTransitMax As Integer
Get
Return _DayInTransitMax
End Get
Set(ByVal value As Integer)
_DayInTransitMax = value
End Set
End Property
''' <summary>
''' If this rate quote was made with shipment size and weight history set this var to true
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property RateBasedOnHistory As Boolean
Get
Return _RateBasedOnHistory
End Get
Set(ByVal value As Boolean)
_RateBasedOnHistory = value
End Set
End Property
End Class
Public Class RateQuote
#Region "Rate Quotes"
Implements IEnumerable
Private _RateQuotes() As RateQuoteType
Public Function GetEnumerator() As IEnumerator _
Implements IEnumerable.GetEnumerator
Return New RateQuoteEnum(_RateQuotes)
End Function
#End Region
End Class
Public Class RateQuoteEnum
Implements IEnumerator
Public _RateEnum() As RateQuoteType
Dim position As Integer = -1
Public Sub New(ByVal list() As RateQuoteType)
_RateEnum = list
End Sub
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
position = position + 1
Return (position < _RateEnum.Length)
End Function
Public Sub Reset() Implements IEnumerator.Reset
position = -1
End Sub
Public ReadOnly Property Current() As Object Implements IEnumerator.Current
Get
Try
Return _RateEnum(position)
Catch ex As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
End Class
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports System.Reflection
Imports System.Collections
Namespace SomethingSomething
''' <summary>
''' Supports sorting of list in data grid view.
''' </summary>
''' <typeparam name="T">Type of object to be displayed in data grid view.</typeparam>
Public Class SortableSearchableList(Of T)
Inherits BindingList(Of T)
#Region "Data Members"
Private _sortDirectionValue As ListSortDirection
Private _sortPropertyValue As PropertyDescriptor = Nothing
''' <summary>
''' Dictionary from property name to custom comparison function.
''' </summary>
Private _customComparisons As New Dictionary(Of String, Comparison(Of T))()
#End Region
#Region "Constructors"
''' <summary>
''' Default constructor.
''' </summary>
Public Sub New()
End Sub
#End Region
#Region "Properties"
''' <summary>
''' Indicates if sorting is supported.
''' </summary>
Protected Overrides ReadOnly Property SupportsSortingCore() As Boolean
Get
Return True
End Get
End Property
''' <summary>
''' Indicates if list is sorted.
''' </summary>
Protected Overrides ReadOnly Property IsSortedCore() As Boolean
Get
Return _sortPropertyValue IsNot Nothing
End Get
End Property
''' <summary>
''' Indicates which property the list is sorted.
''' </summary>
Protected Overrides ReadOnly Property SortPropertyCore() As PropertyDescriptor
Get
Return _sortPropertyValue
End Get
End Property
''' <summary>
''' Indicates in which direction the list is sorted on.
''' </summary>
Protected Overrides ReadOnly Property SortDirectionCore() As ListSortDirection
Get
Return _sortDirectionValue
End Get
End Property
#End Region
#Region "Methods"
''' <summary>
''' Add custom compare method for property.
''' </summary>
''' <param name="propertyName"></param>
''' <param name="compareProperty"></param>
Protected Sub AddCustomCompare(propertyName As String, comparison As Comparison(Of T))
_customComparisons.Add(propertyName, comparison)
End Sub
''' <summary>
''' Apply sort.
''' </summary>
''' <param name="prop"></param>
''' <param name="direction"></param>
Protected Overrides Sub ApplySortCore(prop As PropertyDescriptor, direction As ListSortDirection)
Dim comparison As Comparison(Of T)
If Not _customComparisons.TryGetValue(prop.Name, comparison) Then
' Check to see if the property type we are sorting by implements
' the IComparable interface.
Dim interfaceType As Type = prop.PropertyType.GetInterface("IComparable")
If interfaceType IsNot Nothing Then
comparison = Function(t1 As T, t2 As T) Do
Dim val1 As IComparable = DirectCast(prop.GetValue(t1), IComparable)
Dim val2 As IComparable = DirectCast(prop.GetValue(t2), IComparable)
Return val1.CompareTo(val2)
End Function
Else
' Last option: convert to string and compare.
comparison = Function(t1 As T, t2 As T) Do
Dim val1 As String = prop.GetValue(t1).ToString()
Dim val2 As String = prop.GetValue(t2).ToString()
Return val1.CompareTo(val2)
End Function
End If
End If
If comparison IsNot Nothing Then
' If so, set the SortPropertyValue and SortDirectionValue.
_sortPropertyValue = prop
_sortDirectionValue = direction
' Create sorted list.
Dim _sortedList As New List(Of T)(Me)
_sortedList.Sort(comparison)
' Reverse order if needed.
If direction = ListSortDirection.Descending Then
_sortedList.Reverse()
End If
' Update list.
Dim count As Integer = Me.Count
For i As Integer = 0 To count - 1
Me(i) = _sortedList(i)
Next
' Raise the ListChanged event so bound controls refresh their
' values.
OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
End If
End Sub
' Method below was in the original implementation from MS. Don't know what it's for.
' -- Martijn Boeker, Jan 21, 2010
'protected override void RemoveSortCore()
'{
' //int position;
' //object temp;
' //// Ensure the list has been sorted.
' //if (unsortedItems != null)
' //{
' // // Loop through the unsorted items and reorder the
' // // list per the unsorted list.
' // for (int i = 0; i < unsortedItems.Count; )
' // {
' // position = this.Find(SortPropertyCore.Name,
' // unsortedItems[i].GetType().
' // GetProperty(SortPropertyCore.Name).
' // GetValue(unsortedItems[i], null));
' // if (position >= 0 && position != i)
' // {
' // temp = this[i];
' // this[i] = this[position];
' // this[position] = (T)temp;
' // i++;
' // }
' // else if (position == i)
' // i++;
' // else
' // // If an item in the unsorted list no longer exists, delete it.
' // unsortedItems.RemoveAt(i);
' // }
' // OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
' //}
'}
''' <summary>
''' Ability to search an item.
''' </summary>
Protected Overrides ReadOnly Property SupportsSearchingCore() As Boolean
Get
Return True
End Get
End Property
''' <summary>
''' Finds an item in the list.
''' </summary>
''' <param name="prop"></param>
''' <param name="key"></param>
''' <returns></returns>
Protected Overrides Function FindCore(prop As PropertyDescriptor, key As Object) As Integer
' Implementation not changed from MS example code.
' Get the property info for the specified property.
Dim propInfo As PropertyInfo = GetType(T).GetProperty(prop.Name)
Dim item As T
If key IsNot Nothing Then
' Loop through the the items to see if the key
' value matches the property value.
For i As Integer = 0 To Count - 1
item = DirectCast(Items(i), T)
If propInfo.GetValue(item, Nothing).Equals(key) Then
Return i
End If
Next
End If
Return -1
End Function
''' <summary>
''' Finds an item in the list.
''' </summary>
''' <param name="prop"></param>
''' <param name="key"></param>
''' <returns></returns>
Private Function Find([property] As String, key As Object) As Integer
' Implementation not changed from MS example code.
' Check the properties for a property with the specified name.
Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(GetType(T))
Dim prop As PropertyDescriptor = properties.Find([property], True)
' If there is not a match, return -1 otherwise pass search to
' FindCore method.
If prop Is Nothing Then
Return -1
Else
Return FindCore(prop, key)
End If
End Function
#End Region
End Class
End Namespace
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER