vb- sort list of class by sortexpression - vb.net

I have a class that contains a lot of fields.
I want to order the list of items of my class by one property, then by the other and so on...
I need to do that using SortExpression and SortDirection.
How can I do this in vb?
Dim LsDocuments As List (Of clsDoc) = GetDocuments()
clsDoc is a class with properties:
Date
Hour
Key
Office
I need something like: LsDocuments.orderby("Date","Asc"), and not like LsDocuments.orderby(Functuion(x) x.Date) because it's not general- every time I need to sort by other property (and doing Select case is very not classic).

What I often do is create a property that contains all the values as a string and then sort by that property. Just make sure your string is sortable by making it fixed width. For example:
Public Readonly Property Sort1 as string
Get
Return Date.Tostring("s") & Hour.Tostring.PadLeft(2,"0") & Key.PadRight(50," ") & Office.PadRight(50," ")
End Get
End Property

Related

vb.net list class properties with values

I have a class, and I want to do a custom 'toString' function;
Public Class Person
public property Name as string
public property Age as interger
public Overrides Function ToString() as string
dim BigStr as string = ""
for each Member as MemberInfo in Me.GetType.GetMembers
bigst += Member.Name & " " & [thevalue of this instance]
next
return BigStr
end function
end class
I want it to automatically display all properties with the value of the current instance. But I don't know how to get the value of property without specifically type it out. Is there a dynamic way?
Type.GetMembers returns a list of MemberInfo objects, one per member of the type. However, not all members have values. Fields and properties have values, so if you get the list of just the fields or just the properties, you can ask them for their values. But things like methods don't have a value. You may be able to invoke them and read their return values, but that's different from reading the value of a property or a field.
In other words, you have to work differently with each member, depending on what kind of member it is. Since MemberInfo is the lowest common-denominator, it doesn't have any of the functionality which only works on some of the members. If you want the additional functionality available to you, you'll need to use one of the more specific methods like GetProperties or GetFields.
Since your class contains properties, you probably want to get the list of properties:
Public Class Person
Public Property Name As String
Public Property Age As Integer
Public Overrides Function ToString() As String
Dim bigStr As String = ""
For Each p As PropertyInfo In Me.GetType().GetProperties()
bigStr &= p.Name & " " & p.GetValue(Me)?.ToString()
Next
Return bigStr
End Function
End Class

Retrieve enum name as string

How can I retrieve the name of a enumeration as string? I know you can get the integral value, but this is not what I would like.
I searched the www but it didn't show any good samples.
I made a example class to proper show what I require.
Class test
Public Property PipeEndTreatment As PipeEndTreatmentEnum
Public Enum PipeEndTreatmentEnum
SetOn
SetIn
Offset
OffsetFlush
End Enum
Private Sub TestEnumNameValue()
PipeEndTreatment = PipeEndTreatmentEnum.SetOn
Dim StringValue As String
StringValue = "SetOn" ' This value needs to be generated from the PipeEndTreatment property
End Sub
End Class
Just use ToString(), e.g. PipeEndTreatmentEnum.SetOn.ToString().
Here's another way in case you like longer ways:
[Enum].GetName(PipeEndTreatmentEnum.SetOn.GetType(), PipeEndTreatmentEnum.SetOn)

"default-like" property on non-indexed fields

I have input data that contains strings that represent dates. These may be date strings like "2000-01-01", but they might say "5Y", meaning "five years". So I have a small class to keep track of these...
Public Class FlexDate
Friend Input As String = ""
Friend Value As DateTime = EarliestDate
...
You might find one of these FlexDates inside a Rent object, like "myRent.StartDate". The "problem" is that I would like the Value to be accessed as the field name. For instance...
myRent.StartDate.Input - returns a string
myRent.StartDate.Value - returns a DateTime
So what about....
myRent.StartDate - myRent.StartDate.Value
Is there any way to do this? It's sort of like a default property in a way, but with no index, so I don't think you can use that mechanism in this case?
You could specify the default property using the DefaultMemberAttribute:
<System.Reflection.DefaultMember("Value")> _
Public Class FlexDate
'...
End Class
But this won't help you in VB, because you can't access it. It is just ambiguous - do you mean the object or its property.
But you can implement an implicit conversion:
Class FlexDate
'...
Public Shared Widening Operator CType(this As FlexDate) As DateTime
Return this.Value
End Operator
End Class
Dim date As New FlexDate
Dim value As DateTime = date 'Works with the implicit operator

Best Way to Read Lisbox Array

I am using a sql query to retrieve data and write to a listbox. However, sometimes an item may have more than one value.
IE:
Data: "Patient Disclosure"
Value: "Encounter"
or
Data: "Patient Disclosure"
Value: "Order"
In the listbox, the line item will show only "Patient Disclosure" but I have the values written in the array. However, I don't want two of the same line item to appear. The "order" value should be the only one showing if it has multiple values. How can I do this?
While reader.Read()
Dim Myitem As New List(Of myitems)
Myitem.Add(New myitems with {.Description = reader(0), .Value = reader(2)})
' If reader(2) = "Order" Then
' listBox1.Items.Add(Myitem.ToArray)
' Else
' listBox1.Items.Add(reader(0))
' End If
listBox1.Items.AddRange(Myitem.ToArray)
End While
You can eliminate duplicates with
listBox1.Items.AddRange(Myitem.Distinct().ToArray())
However, I am not sure what you are asking. I good thing to do is to create a class that holds your data, instead of working directly with data readers, as you have done already. Give it a more descriptive name than myitems. As developers we are constantly working with many kinds of "items".
Public Class Patient // Or whatever the items are supposed to represent.
Public Property Description As String
Public Property Value As String
Public Overrides Function ToString() As String
Return String.Format("Description = {0}, Value = {1}", Description, Value)
End Function
End Class
If you then add Patient objects to a ListBox, the ListBox will automatically use ToString to display the items.
You can also override Equals and GetHashCode in order to influence the way two objects are compared. The Distinct method will use these two methods in order to do its job. See: Implementing the Equals Method

Possible to add some sort of identification onto list items?

I'm just curious if it's possible to gather a list of data and put it into a list or array and easily pull them out using some variable(like a tag property on controls) on each item in the list rather than using the index. An example would be if i have many controls on a form and would like to populate the values using the list but instead of having to cross check a lot of different indicies(would take a lot of time) i could just assign the label to some 'tag like' variable for the list item.
Is this possible?
Lists in .NET, such as the List(Of T) class, only support storing one object per item. However, the beauty of them is, you can store any type of object that you want. If you need to store metadata with your data, simply create a new class that holds all the data for each item. For instance:
Public Class MyControlData
Public Property LabelText As String
Public Property Value As String
End Class
Then you can add the items to the list like this:
Dim dataList As New List(Of MyControlData)()
Dim item As New MyControlData()
item.LabelText = "Name"
item.Value = "Bob"
dataList.Add(item)
And you can read the data from the list like this:
For Each i As MyControlData in dataList
Label1.Text = i.LabelText
TextBox1.Text = i.Value
Next
I would use a Dictionary object so you can use a key to reference your data easily.
You can use LINQ:
Dim myTagControls = From ctrl In Me.Controls.Cast(Of Control)()
Where "your-tag".Equals(ctrl.Tag)
For Each ctrl In myTagControls
Console.WriteLine("Tag:{0} Name:{1}", ctrl.Tag, ctrl.Name)
Next