none
Use a string to reference an object

    Question

  • This was an assignment I finished the other night by using a series of If statements. We were required to use a listarray. I'm asking this question because I want to understand why my initial approach didn't work. 

    I want to use a string variable to sort the array by one of the three 'fields'(I can't recall the correct term for the fields). The variable I created for this is SortBy. I've played around with methods functions and whatnot in the Stock class but have had no luck. I suspect the problem is that I don't understand exactly what value I need to assign to SortBy. 

    Here is the code from the main form:

    
    Public Class Form1
    
        Public rButton As RadioButton
        Dim stockList As New List(Of Stock)
    
        Private Property SortBy As Object
    
        Private Sub Form1_Load() Handles Me.Load
    
            rButton = Me.Controls.OfType(Of RadioButton).Where(Function(r) r.Checked = True).FirstOrDefault()
    
            With stockList
                .Add(New Stock("ABC", 80, 4.0))
                .Add(New Stock("LLT", 43, 8.6))
                .Add(New Stock("MMA", 40, 8.0))
                .Add(New Stock("SBA", 42, 7))
                .Add(New Stock("XYZ", 77, 4))
            End With
        End Sub
    
    
        Sub Sort()
            rButton = Me.Controls.OfType(Of RadioButton).Where(Function(r) r.Checked = True).FirstOrDefault()
            Stock.SortBy = rButton.Name.Replace("Sort", ""))
    
    
    
            If rButton.Name = "SortPrice" Then
                Dim search = From aStock In stockList
                         Select aStock
                            Order By aStock.SortBy
    
                For Each Record In search
                    ListBox1.Items.Add(Record.SortBy)
                Next
    
            End If
    
            'Temporary Items to check what name is being found
            Dim name = Convert.ToString(rButton.Name)
            Label2.Text = name
    
        End Sub
    
        Private Sub radSortTicker_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SortTickNames.CheckedChanged
            Sort()
        End Sub
    
        Private Sub radSortPrice_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SortPrice.CheckedChanged
            Sort()
        End Sub
    
        Private Sub radSortPE_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SortRatio.CheckedChanged
            Sort()
        End Sub
    
    
    End Class
    

    And here is the code for the Stock class:

    Public Class Stock
    
        Private _p1 As String
        Private _p2 As Integer
        Private _p3 As Integer
    
        Sub New(ByVal Ticker As String, ByVal Price As Integer, ByVal Ratio As Integer)
            ' TODO: Complete member initialization 
            _p1 = Ticker
            _p2 = Price
            _p3 = Ratio
        End Sub
    
        Public Property TickName() As String
        Public Property Price() As String
        Public Property Ratio() As String
    
        Public ReadOnly Property peRatio()
            Get
                Return Price / Ratio
            End Get
        End Property
    
    End Class
    

    I appreciate any help you can give me.

    Thursday, February 07, 2013 11:44 PM

Answers

  • You don't need a sortby variable, but you do need to detect which radiobutton is now checked, because you will only do the sort for the one that's checked.  That's difficult with your existing design, because you are trying to search the radiobuttons in the sort routine.  Instead, do the validation at the event handler, and advise the sort function of what it needs to sort on.  The function argument is what you were trying to make the SortBy variable do.  Passing an argument makes the sort independent of how it was selected.

        Sub Sort(SortType As Integer)
            Select Case SortType
               Case 0  'Ticker sort
                  Dim search = From aStock In stockList
                         Select aStock
                            Order By aStock.Ticker
    
                  For Each Record In search
                    ListBox1.Items.Add(Record.Ticker)
                  Next
                Case 1  'Price Sort
                    'Duplicate for search type 1
                Case 2  'Ratio Sort
                    'Duplicate for search type 2
              End Select
            Label2.Text = SortType.ToString
    
        End Sub
    
        Private Sub radSortTicker_CheckedChanged(ByVal sender As RadioButton, ByVal e As System.EventArgs) Handles SortTickNames.CheckedChanged
            If sender.Checked Then Sort(0)
        End Sub
    
        Private Sub radSortPrice_CheckedChanged(ByVal sender As RadioButton, ByVal e As System.EventArgs) Handles SortPrice.CheckedChanged
            If sender.Checked Then Sort(1)
        End Sub
    
        Private Sub radSortPE_CheckedChanged(ByVal sender As RadioButton, ByVal e As System.EventArgs) Handles SortRatio.CheckedChanged
            If sender.Checked Then Sort(2)
        End Sub
    

    0, 1 and 2 as used here should actually be an enum.

    • Marked as answer by SlimisJim Friday, February 08, 2013 10:41 PM
    Friday, February 08, 2013 12:33 AM

All replies

  • Start changing your radiobuttons for checkboxes. 

    If an enduser change one radiobutton, then all other ones changes too.

    So all your events are handled.


    Success
    Cor

    Friday, February 08, 2013 12:05 AM
  • You don't need a sortby variable, but you do need to detect which radiobutton is now checked, because you will only do the sort for the one that's checked.  That's difficult with your existing design, because you are trying to search the radiobuttons in the sort routine.  Instead, do the validation at the event handler, and advise the sort function of what it needs to sort on.  The function argument is what you were trying to make the SortBy variable do.  Passing an argument makes the sort independent of how it was selected.

        Sub Sort(SortType As Integer)
            Select Case SortType
               Case 0  'Ticker sort
                  Dim search = From aStock In stockList
                         Select aStock
                            Order By aStock.Ticker
    
                  For Each Record In search
                    ListBox1.Items.Add(Record.Ticker)
                  Next
                Case 1  'Price Sort
                    'Duplicate for search type 1
                Case 2  'Ratio Sort
                    'Duplicate for search type 2
              End Select
            Label2.Text = SortType.ToString
    
        End Sub
    
        Private Sub radSortTicker_CheckedChanged(ByVal sender As RadioButton, ByVal e As System.EventArgs) Handles SortTickNames.CheckedChanged
            If sender.Checked Then Sort(0)
        End Sub
    
        Private Sub radSortPrice_CheckedChanged(ByVal sender As RadioButton, ByVal e As System.EventArgs) Handles SortPrice.CheckedChanged
            If sender.Checked Then Sort(1)
        End Sub
    
        Private Sub radSortPE_CheckedChanged(ByVal sender As RadioButton, ByVal e As System.EventArgs) Handles SortRatio.CheckedChanged
            If sender.Checked Then Sort(2)
        End Sub
    

    0, 1 and 2 as used here should actually be an enum.

    • Marked as answer by SlimisJim Friday, February 08, 2013 10:41 PM
    Friday, February 08, 2013 12:33 AM
  • If an enduser change one radiobutton, then all other ones changes too.

    That's what OP wants to happen - it's the reason for using a radiobutton.   The code simply needs a test for whether the radiobutton is checked or not.

    Friday, February 08, 2013 12:36 AM
  • Try this as well:

    Dim n As String = rButton.Name

    Dim search = _

                  From aStock In stockList

                  Select aStock

                  Order By If(n = "TickName", aStock.TickName,

                              If(n = "SortPrice", CObj(aStock.Price,

                                 If(n = "Ratio", CObj(aStock.Ratio), Nothing)))

    Specify the correct names of radiobuttons.

    Note that your Stock class does not initialize properties. You should remove _p1 and use ‘Me.TickName = Ticker’ etc. inside the New. Also use appropriate types instead of strings, for example Decimal for prices. Add 'Option Strict On' on first line to detect more issues.

    • Edited by Viorel_MVP Friday, February 08, 2013 7:42 AM
    Friday, February 08, 2013 7:29 AM
  • If an enduser change one radiobutton, then all other ones changes too.

    That's what OP wants to happen - it's the reason for using a radiobutton.   The code simply needs a test for whether the radiobutton is checked or not.

    Acamar,

    Are you the OP and are you using more accounts?

    However, what you tell is one solution, there are many more. 


    Success
    Cor


    Friday, February 08, 2013 11:59 AM
  • I wrote about the radiobuttons, personally I would use a checkbox or a button with an image on it. 

    But that is not so important, in your current code it gives strange behavior. 

    However, comming back to your real question and trying to answer that I see you miss some knowledge. I assume that I can fill that gap with this.

    Call your sort with 

    Sort(DirectCast(sender, RadioButton)) 'whatever control you use

    And then in your current code change the first rows with 

     Sub Sort(RButton As RadioButton)
            Stock.SortBy = RButton.Name.Replace("Sort", "")

    Be aware that this kind of loosely bound programming with strings, has many changes on mistakes at maintance time.


    Success
    Cor


    Friday, February 08, 2013 12:16 PM
  • Thank you for the quick response. It's not quite what I was looking for, but I understand why my previous method wasn't working. 
    Friday, February 08, 2013 10:43 PM
  • Thank you for the alternative solution and the bit about classes and properties. 
    Friday, February 08, 2013 10:50 PM
  • I think Cor is alluding to the fact that you often need to sort by multiple properties, although in this example, it might not be appropriate.
    Friday, February 08, 2013 11:39 PM