How to sort a custom list - SecondaryItem within PrimaryItem - vb.net

Hi there have a list of custom objects that I need to be able to sort, one property within another. How do I go about doing this using .Net. Normally I would carry out all sorting requirements within the SQL that delivers the data, unfortunately in this case I don't have control over that generation of the raw data. I consequently have no experience of sorting content using .Net functions such as Linq and/or IComparable. An impression of the code elements involved are listed below:
Public Class CustomObject
Public Property PrimaryItem As String
Get
Return _primaryItem
End Get
Set(ByVal value As String)
_primaryItem = value
End Set
End Property
Public Property SecondaryItem As String
Get
Return _secondaryItem
End Get
Set(ByVal value As String)
_secondaryItem = value
End Set
End Property
End Class
Public Class CustomObjectList
Inherits List(Of CustomObject)
Public Sub New()
End Sub
End Class
In essence I want to be able to sort CustomObjectList according to SecondaryItem within PrimaryItem:
PrimaryItem1
SecondaryItem1
SecondaryItem2
etc...
PrimaryItem2
SecondaryItem1
SecondaryItem2
etc...
etc...
Hoping that some kind person will be able to give me a 'leg up' in usage of either Linq and/or iComparable.

Dim result = MyList.OrderBy(Function(x) x.PrimaryItem).ThenBy(Function(x) x.SecondaryItem)

Related

Class with public properties as list of structures for saving a communcation protocol

I want to save a communication inside a class. After that I plan to serialize the class o a XML file, where all datapoints are decoded between a tag.
Therefore I want to explain my communication protocol first.
The message Frame Looks like the following
LIE01
LIE02
When the communication ends, I have around 3000 of this telegrams inside a raw variable.
Here I describe the Messages:
LIE01: Header + 1 data word
LIE02: Header + 2 data words
My idea was to decode the frame and save it in a list (or array) of structures that are public properties of my class.
Public Class Com
Public Structure sLIE01
Public Property Header As Int16
Public Property data1 As Int16
End Structure
Public Structure sLIE02
Public Property Header As Int16
Public Property data1 As Int16
Public Property data2 As Int16
End Structure
Public Property LIE01 As List(Of sLIE01)
Get
?
End Get
Set(ByVal value As List(Of sLIE01))
?
End Set
End Property
Public Property LIE02 As List(Of sLIE02)
Get
?
End Get
Set(ByVal value As List(Of sLIE02))
?
End Set
End Property
End Class
Unfortunatelly I am more a beginner than an expert, so that I have no idea, how to write the code to Set or Get a specific LIE message.
Even I'm not sure, whether my way is a common way for this purpose or not.
You could use auto implemented properties in your code and skip getters and setters altogether (https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/procedures/auto-implemented-properties). You'll then be able to assign lists to them like:
Dim newList as new List(of sLIE01)()
ComInstance.Lie01 = newList
You can also operate on those list properties directly (just make sure you initialize them in class constructor to avoid NullReferenceException):
Dim lie as sLie01
ComInstance.Lie01.Add(lie)
Also consider replacing structures with classes: https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/structures-and-classes
If you still want to use Get Set it would look like this...
Private _LIE01 As List(Of sLIE01)
Public Property LIE01 As List(Of sLIE01)
Get
Return _LIE01
End Get
Set(value as List(Of sLIE01))
_LIE01 = value
End Set
End Property

nhibernate fill class with custom data from different tables

I have a web application (asp.net + SQL db) and I'm mapping it with nHibernate with relative success =).
This web reads an Oracle db (from an ERP system), collects and display data from it but its not using nHibernate for this task.
I have done several reports each one with its own vb.net class that I fill with intrincated queries,
collecting data from a bunch of Oracle tables. So my question is:
Can i do an specific hql query and fill my vb.class in a custom way (Maybe not mapping it), specifying one by one which column of my query fills each property?
===================== EDIT WITH SOLUTION =====================
Just if someone need the resolution, I post the solution in an example.
Public Class classExample
Private pProperty1 As Decimal
Private pProperty2 As String
Public Property Property1() As Decimal
Get
Property1 = pProperty1
End Get
Set(ByVal Value As Decimal)
pProperty1 = Value
End Set
End Property
Public Property Property2() As String
Get
Property2 = pProperty2
End Get
Set(ByVal Value As String)
pProperty2 = Value
End Set
End Property
Public Overloads Function Load() As System.Collections.Generic.List(Of classExample)
Using session As NHibernate.ISession = ISessionFactory.OpenSession()
Dim strsql As String = "SELECT.... FROM...."
Dim Query As NHibernate.IQuery = session.CreateSQLQuery(strsql)
Query.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(Of classExample))
Return Query.List(Of classExample)()
End Using
End Function
End Class
Thanks for your help.
You need to use a result transformer as here (see second code block).

How to instantiate Class object with varying number of property values

Been working a lot with custom classes lately and I love the power you can have with them but I have come across something that I'm not able to solve and/or find anything helpful online.
I have a list of a class with properties I'm looking to only store information pulled from a database into.
Public Class CustomClass
Public _Values As String
Public _Variables As String
Public ReadOnly Property Values() As String
Get
Return _Values
End Get
End Property
Public ReadOnly Property Variables() As String
Get
Return _Variables
End Get
End Property
Sub New(ByVal values As String, ByVal variables As String)
_Values = values
_Variables = variables
End Sub
End Class
I will be iterating through some database entries, and I'm looking to store them into the appropriate property when I hit them (since I won't have them all available immediately, which is part of my problem). I want to just be able to add either the value or the variable at a time and not both of them, but since I have the sub procedure 'New' passing two arguments, it will always require passing them both. I've found the only way around this is by making them optional fields which I don't feel is the right way to solve this. Is what I'm looking to do possible with a class or would it be simpler by using a structure?
You can overload the constructor:
Friend Class Foo
' using auto-implement props:
Public Property Name As String ' creates a _Name backing field
Public Property Value as Integer
Public Sub New(newN as String, newV as Integer)
' access "hidden" backing fields if you want:
_Name = newN
_Value = newV
End Sub
Public Sub New() ' simple ctor
End Sub
Public Sub New(justName As String)
' via the prop
Name = justName
End Sub
End Class
You now have 3 ways to create the object: with full initialization, partial (name only) or as a blank object. You will often need a "simple constructor" - one with no params - for other purposes: serializers, Collection editors and the like will have no idea how to use the parameterized constructors and will require a simple one.
If rules in the App were that there was no reason for a MyFoo to ever exist unless both Name and Value being defined, implementing only the New(String, Integer) ctor enforces that rule. That is, it is first about the app rules, then about coding convenience.
Dim myFoo As New Foo ' empty one
myFoo.Name = "ziggy" ' we only know part of it
Since the default of string is nothing, you could pass nothing for the value you don't have. IE
Collection.Add(New CustomClass("My Value",Nothing))
Every type has a default, so this works with more than just strings.

How to iterate through a property of a class in VB?

If I have a class object A, and it has properties such as a0, a1, a2... If this class has 100 properties like this (up to a99). I would like to display each of these properties, but I do not want to have 100 lines of code of calling this as following
print A.a0
print A.a1
print A.a2
...
print A.a99
The code is too inefficient, so I am wondering if there is a way to loop through these properties. Thank you.
.NET provides the ability to examine an object at runtime through a process known as reflection. The purpose of the original post was to iterate through an object's properties in an automated fashion rather than by manually coding explicit statements that displayed each property, and reflection is a process to accomplish this very thing.
For this particular purpose, looping through an object's properties at run-time, you use the GetProperties() method that is available for each Type. In your case, the Type you want to "reflect" is A, so the type-specific version of GetProperties returns a list of the instance properties for that object.
When you ask .NET to return the properties of an object, you can also specify what's called a binding flag that tells .NET which properties to return - public properties, private properties, static properties - a myriad of combinations from about twenty different values in the BindingFlags enumeration. For the purposes of this illustration, BindingFlags.Public will suffice, assuming your A0-A999 properties are declared to be public. To expose even more properties, simply combine multiple BindingFlag values with a logical "or".
So, now armed with that information, all we need to do is create a class, declare its properties, and tell Reflection to enumerate the properties for us. Assuming your Class A exists with property names A0-A999 already defined, here's how you'd enumerate ones starting with "A":
// Assuming Class "A" exists, and we have an instance of "A" held in
// a variable ActualA...
using System.Reflection
// The GetProperties method returns an array of PropertyInfo objects...
PropertyInfo[] properties = typeof(ActualA).GetProperties(BindingFlags.Public);
// Now, just iterate through them.
foreach(PropertyInfo property in properties)
{
if (property.Name.StartsWith("A")){
// use .Name, .GetValue methods/props to get interesting info from each property.
Console.WriteLine("Property {0}={1}",property.Name,
property.GetValue(ActualA,null));
}
}
There you have it. That's C# version rather than VB, but I think the general concepts should translate fairly readily. I hope that helps!
This MSDN code sample illustrates how to iterate over a class's properties using reflection:
http://msdn.microsoft.com/en-us/library/kyaxdd3x.aspx#Y900
Create a VB.Net Console application, copy and paste this code into the Module1.vb file and run it.
Module Module1
Sub Main()
For Each prop In GetType(TestClass).GetProperties()
Console.WriteLine(prop.Name)
Next
Console.ReadKey(True)
End Sub
End Module
Public Class TestClass
Private _One As String = "1"
Public Property One() As String
Get
Return _One
End Get
Set(ByVal value As String)
_One = value
End Set
End Property
Private _Two As Integer = 2
Public Property Two() As Integer
Get
Return _Two
End Get
Set(ByVal value As Integer)
_Two = value
End Set
End Property
Private _Three As Double = 3.1415927
Public Property Three() As Double
Get
Return _Three
End Get
Set(ByVal value As Double)
_Three = value
End Set
End Property
Private _Four As Decimal = 4.4D
Public Property Four() As Decimal
Get
Return _Four
End Get
Set(ByVal value As Decimal)
_Four = value
End Set
End Property
End Class

Access variable of child form

Using VB.Net
I have about 60 Child forms
Each have a variable with same name.
In Main form I want to set the value of the variable of the active child.
One way of doing that is like
Select Case Me.ActiveMdiChild.Name
Case "formName"
frmformName.Variable=0
I donot want to do that as it involves writing many cases and I may miss some.
Is there some other way of doing it .
I tried
Dim O as Object = Me.ActiveMdiChil
O.VariableName= 0
and its various variants but its not working
Another way to do that is with an Interface, example:
Public Interface IChildVariable
Property Variable() As Integer
End Interface
Public Class Form1
Implements IChildVariable
Private _MyVariable As Integer
Public Property Variable() As Integer Implements IChildVariable.Variable
Get
Return _MyVariable
End Get
Set(ByVal value As Integer)
_MyVariable = value
End Set
End Property
End Class
Then you can just have a single check point:
If TypeOf Me.ActiveMdiChild Is IChildVariable Then
DirectCast(Me.ActiveMdiChild, IChildVariable).Variable = 0
Else
''Throw Exception
End If