Tag Archives: vb.net
VB.NET || How To Add Simple Object Change Tracking To Track Changes Using VB.NET
The following is a module with functions which demonstrates how to add simple object change tracking to track changes made to an object using VB.NET.
Contents
1. Overview
2. Basic Usage
3. Accept Changes
4. Reject Changes
5. Ignore Tracking For Property
6. Notify Property Changed
7. Utils Namespace
8. More Examples
1. Overview
The following is a simple abstract change tracker class which implements INotifyPropertyChanged and IRevertibleChangeTracking which provides functionality to track object changes, and to ‘accept’ or ‘revert’ changes.
To use this class, simply inherit the abstract class, and your all set!
Note: Don’t forget to include the ‘Utils Namespace‘ before running the examples!
2. Basic Usage
The example below demonstrates the use of ChangeTracker.BeginChanges to start tracking object changes, as well as ChangeTracker.GetChanges to get the changes made to an object.
The following example demonstrates the basic usage of adding change tracking to an object, and making and getting changes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
' Basic Usage Imports Utils ' Declare class and inherit ChangeTracker Public Class Person : Inherits ChangeTracker Public Property FirstName As String Public Property LastName As String Public Property Age As Integer? End Class ' Declare data Dim person = New Person With { .FirstName = "Kenneth", .LastName = "Perkins", .Age = 31 } ' Required: Changes made to this object will start being ' tracked the moment this function is called person.BeginChanges() ' Make changes to the object person.FirstName = "Jennifer" person.LastName = "Nguyen" person.Age = 28 ' Get changes made to the object Dim changes = person.GetChanges() ' Display the changes Debug.Print($"Changes: {changes.Count}") For Each change In changes Debug.Print($" PropertyName: {change.PropertyName}, OriginalValue: {change.OriginalValue}, CurrentValue: {change.CurrentValue}") Next ' expected output: ' Changes: 3 ' PropertyName: FirstName, OriginalValue: Kenneth, CurrentValue: Jennifer ' PropertyName: LastName, OriginalValue: Perkins, CurrentValue: Nguyen ' PropertyName: Age, OriginalValue: 31, CurrentValue: 28 |
3. Accept Changes
The example below demonstrates the use of ChangeTracker.AcceptChanges to accept modification changes made to an object.
This function commits all the changes made to the object since either ChangeTracker.BeginChanges was called, or since ChangeTracker.AcceptChanges was last called.
When the accept function is called, all the changes made to the object up to that point will be marked as the current ‘source of truth’ for change tracking.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
' Accept Changes Imports Utils ' Declare class and inherit ChangeTracker Public Class Person : Inherits ChangeTracker Public Property FirstName As String Public Property LastName As String Public Property Age As Integer? End Class ' Declare data Dim person = New Person With { .FirstName = "Kenneth", .LastName = "Perkins", .Age = 31 } ' Required: Changes made to this object will start being ' tracked the moment this function is called person.BeginChanges() ' Make changes to the object person.FirstName = "Lynn" person.LastName = "P" person.Age = 10 ' Accept all the changes made to the object up to ' this point as the source of truth for change tracking person.AcceptChanges() ' Get changes made to the object Dim changes = person.GetChanges() ' Display the changes ' Note: No changes will display because the most recent modifications has been accepted Debug.Print($"Changes: {changes.Count}") For Each change In changes Debug.Print($" PropertyName: {change.PropertyName}, OriginalValue: {change.OriginalValue}, CurrentValue: {change.CurrentValue}") Next ' expected output: ' Changes: 0 |
4. Reject Changes
The example below demonstrates the use of ChangeTracker.RejectChanges to reject modification changes made to an object.
This function rejects all the changes made to the object since either ChangeTracker.BeginChanges was called, or since ChangeTracker.AcceptChanges was last called.
When the reject function is called, all the changes made to the object up to that point reverts back to the objects state before modifications initially began or modifications was last accepted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
' Reject Changes Imports Utils ' Declare class and inherit ChangeTracker Public Class Person : Inherits ChangeTracker Public Property FirstName As String Public Property LastName As String Public Property Age As Integer? End Class ' Declare data Dim person = New Person With { .FirstName = "Kenneth", .LastName = "Perkins", .Age = 31 } ' Required: Changes made to this object will start being ' tracked the moment this function is called person.BeginChanges() ' Make changes to the object person.FirstName = "Sole" person.LastName = "P" person.Age = 19 ' Rejects all the changes made to the object up to ' this point and reverts back to the objects state ' before modifications were made person.RejectChanges() ' Get changes made to the object Dim changes = person.GetChanges() ' Display the changes ' Note: No changes will display because the most recent modifications has been rejected Debug.Print($"Changes: {changes.Count}") For Each change In changes Debug.Print($" PropertyName: {change.PropertyName}, OriginalValue: {change.OriginalValue}, CurrentValue: {change.CurrentValue}") Next ' expected output: ' Changes: 0 |
5. Ignore Tracking For Property
The example below demonstrates the use of ChangeTracker.ChangeTrackerIgnore attribute to mark a specific property to be ignored from change tracking.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
' Ignore Tracking For Property Imports Utils ' Declare class and inherit ChangeTracker Public Class Person : Inherits ChangeTracker Public Property FirstName As String Public Property LastName As String <ChangeTrackerIgnore> Public Property Age As Integer? End Class ' Declare data Dim person = New Person With { .FirstName = "Kenneth", .LastName = "Perkins", .Age = 31 } ' Required: Changes made to this object will start being ' tracked the moment this function is called person.BeginChanges() ' Make changes to the object person.FirstName = "Jennifer" person.LastName = "Nguyen" person.Age = 28 ' Get changes made to the object Dim changes = person.GetChanges() ' Display the changes Debug.Print($"Changes: {changes.Count}") For Each change In changes Debug.Print($" PropertyName: {change.PropertyName}, OriginalValue: {change.OriginalValue}, CurrentValue: {change.CurrentValue}") Next ' expected output: ' Changes: 2 ' PropertyName: FirstName, OriginalValue: Kenneth, CurrentValue: Jennifer ' PropertyName: LastName, OriginalValue: Perkins, CurrentValue: Nguyen |
6. Notify Property Changed
The example below demonstrates the use of ChangeTracker.NotifyPropertyChanged to fire the PropertyChanged event notifying that the specified property value has changed.
In the class declaration, simply add ChangeTracker.NotifyPropertyChanged to the properties you wish to notify changes, and add a PropertyChanged event handler function to receive the notifications.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
' Notify Property Changed Imports Utils ' Declare class and inherit ChangeTracker ' Modify the properties you wish to notify changes Public Class Person : Inherits ChangeTracker Private _firstName As String Public Property FirstName As String Get Return _firstName End Get Set(value As String) _firstName = value NotifyPropertyChanged(value) End Set End Property Private _lastName As String Public Property LastName As String Get Return _lastName End Get Set(value As String) _lastName = value NotifyPropertyChanged(value) End Set End Property Private _age As Integer? Public Property Age As Integer? Get Return _age End Get Set(value As Integer?) _age = value NotifyPropertyChanged(value) End Set End Property End Class ' Declare data Dim person = New Person With { .FirstName = "Kenneth", .LastName = "Perkins", .Age = 31 } ' Set custom event handler function for property changed event AddHandler person.PropertyChanged, AddressOf Person_PropertyChanged ' Required: Changes made to this object will start being ' tracked the moment this function is called person.BeginChanges() ' Make changes to the object person.FirstName = "Jennifer" person.LastName = "Nguyen" person.Age = 28 ' Declare Custom event handler function for the PropertyChanged event Public Sub Person_PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Dim eventArgs = CType(e, ChangeTracker.PropertyChangedTrackedEventArgs) Debug.Print($"Event Handler Changes:") Debug.Print($" PropertyName: {eventArgs.PropertyName}, OriginalValue: {eventArgs.OriginalValue}, CurrentValue: {eventArgs.CurrentValue}") End Sub ' expected output: ' Event Handler Changes: ' PropertyName: FirstName, OriginalValue: Kenneth, CurrentValue: Jennifer ' Event Handler Changes: ' PropertyName: LastName, OriginalValue: Perkins, CurrentValue: Nguyen ' Event Handler Changes: ' PropertyName: Age, OriginalValue: 31, CurrentValue: 28 |
7. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Apr 23, 2022 ' Taken From: http://programmingnotes.org/ ' File: Utils.cs ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Imports System Imports System.Linq Imports System.Reflection Imports System.Collections.Generic Imports System.Runtime.CompilerServices Imports System.ComponentModel Namespace Global.Utils Public MustInherit Class ChangeTracker : Implements System.ComponentModel.INotifyPropertyChanged, System.ComponentModel.IRevertibleChangeTracking Protected Property Tracked As Dictionary(Of String, ITrackedChange) Public Event PropertyChanged As System.ComponentModel.PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged Public ReadOnly Property IsTracking As Boolean Get Return Tracked.Count > 0 End Get End Property ''' <summary> ''' Gets the objects changed status ''' </summary> ''' <returns><see langword="true"/> if the objects content has changed since either <see cref="BeginChanges"/> ''' was called, or since <see cref="AcceptChanges"/> was last called; <see langword="false"/> otherwise</returns> Public Property IsChanged As Boolean Implements IRevertibleChangeTracking.IsChanged Get If Not _isChanged AndAlso IsTracking Then Dim trackedChanges = GetTrackedChanges() If trackedChanges.Any(Function(x) x.DetectChange(GetValue(x.Property))) Then _isChanged = True End If End If Return _isChanged End Get Protected Set(value As Boolean) _isChanged = value End Set End Property Private _isChanged As Boolean = False Protected Sub New() Tracked = New Dictionary(Of String, ITrackedChange)() End Sub ''' <summary> ''' Fires the PropertyChanged event notifying that the specified property value changed ''' </summary> ''' <param name="currentValue">The current value</param> ''' <param name="originalValue">The original value</param> ''' <param name="propertyName">The corresponding property name</param> Protected Sub NotifyPropertyChanged(currentValue As Object, originalValue As Object, <CallerMemberName> Optional propertyName As String = "") RaiseEvent PropertyChanged(Me, New PropertyChangedTrackedEventArgs(propertyName, originalValue, currentValue)) End Sub ''' <summary> ''' Fires the PropertyChanged event notifying that the specified property value changed ''' </summary> ''' <param name="currentValue">The current value</param> ''' <param name="propertyName">The corresponding property name</param> Protected Overridable Sub NotifyPropertyChanged(currentValue As Object, <CallerMemberName> Optional propertyName As String = "") NotifyPropertyChanged(currentValue, GetTrackedChange(propertyName)?.OriginalValue, propertyName) End Sub ''' <summary> ''' Starts the tracking operation on the object. Changes made to the ''' object will start being tracked the moment this function is called ''' </summary> ''' <exception cref="InvalidOperationException">Changes have already begun</exception> Public Overridable Sub BeginChanges() ThrowIfTrackingStarted() Track(GetTrackableProperties()) IsChanged = False End Sub ''' <summary> ''' Ends the tracking operation on the object. Any pending tracked changes made to the ''' object since either <see cref="BeginChanges"/> was called, or since <see cref="AcceptChanges"/> ''' was last called will be lost the moment this function is called ''' </summary> ''' <exception cref="InvalidOperationException">Change tracking has not started</exception> Public Overridable Sub EndChanges() ThrowIfTrackingNotStarted() Tracked.Clear() IsChanged = False End Sub ''' <summary> ''' Sets the current object state as its default state by accepting the modifications. ''' Commits all the changes made to this object since either <see cref="BeginChanges"/> ''' was called, or since <see cref="AcceptChanges"/> was last called ''' </summary> ''' <exception cref="InvalidOperationException">Change tracking has not started</exception> Public Overridable Sub AcceptChanges() Implements IChangeTracking.AcceptChanges ThrowIfTrackingNotStarted() Dim trackedChanges = UpdateTracked() For Each change In trackedChanges change.AcceptChange() Next IsChanged = False End Sub ''' <summary> ''' Resets the current objects state by rejecting the modifications. Rejects ''' all changes made to the object since either <see cref="BeginChanges"/> ''' was called, or since <see cref="AcceptChanges"/> was last called ''' </summary> ''' <exception cref="InvalidOperationException">Change tracking has not started</exception> Public Overridable Sub RejectChanges() Implements IRevertibleChangeTracking.RejectChanges ThrowIfTrackingNotStarted() Dim trackedChanges = GetTrackedChanges() For Each change In trackedChanges SetValue(change.[Property], change.OriginalValue) change.RejectChange() Next IsChanged = False End Sub ''' <summary> ''' Returns a list containing information of all the properties with changes ''' applied to it since either <see cref="BeginChanges"/> was called, or ''' since <see cref="AcceptChanges"/> was last called ''' </summary> ''' <returns>A list containing the changes made to the object</returns> ''' <exception cref="InvalidOperationException">Change tracking has not started</exception> Public Overridable Function GetChanges() As List(Of ITrackedChange) ThrowIfTrackingNotStarted() Dim result = New List(Of ITrackedChange)() Dim trackedChanges = UpdateTracked() For Each change In trackedChanges If change.HasChanges Then result.Add(change) End If Next Return result End Function ''' <summary> ''' Returns a list containing information of all the properties being tracked ''' </summary> ''' <returns>A list containing property tracking information</returns> ''' <exception cref="InvalidOperationException">Change tracking has not started</exception> Public Function GetTracked() As List(Of ITrackedChange) ThrowIfTrackingNotStarted() Return Tracked.Values.ToList() End Function ''' <summary> ''' Updates the tracking status of all the properties being tracked ''' </summary> ''' <returns>A list containing properties being tracked</returns> Protected Function UpdateTracked() As IEnumerable(Of TrackedChange) Dim trackedChanges = GetTrackedChanges() Track(trackedChanges.Select(Function(x) x.Property)) Return trackedChanges End Function ''' <summary> ''' Keeps track of the original and current values of the provided properties ''' </summary> ''' <param name="properties">The properties to track</param> Protected Sub Track(properties As IEnumerable(Of PropertyInfo)) If properties IsNot Nothing Then For Each prop In properties Track(prop, GetValue(prop)) Next End If End Sub ''' <summary> ''' Keeps track of the original and current value of the provided property ''' </summary> ''' <param name="property">The property to track</param> ''' <param name="currentValue">The current value of the property</param> Protected Sub Track([property] As PropertyInfo, currentValue As Object) Dim currentChange As TrackedChange = Nothing If Not IsTrackedChange([property].Name) Then Dim hasChangedFunc As Func(Of Object, Object, Boolean) = Function(original, current) Return HasValuesChanged(original, current) End Function currentChange = New TrackedChange With { .Property = [property], .OriginalValue = currentValue, .HasChangedFunc = hasChangedFunc } Tracked.Add([property].Name, currentChange) Else currentChange = GetTrackedChange([property].Name) currentChange.CurrentValue = currentValue currentChange.Status = TrackedChange.TrackingStatus.Checked currentChange.LastChecked = Date.Now End If If currentChange.HasChanges Then IsChanged = True End If End Sub ''' <summary> ''' Class which contains property tracking information ''' </summary> Protected Class TrackedChange : Implements ITrackedChange Public Enum TrackingStatus Unchecked Checked End Enum Public Property [Property] As PropertyInfo Public ReadOnly Property PropertyName As String Implements ITrackedChange.PropertyName Get Return [Property]?.Name End Get End Property Public Property OriginalValue As Object Implements ITrackedChange.OriginalValue Public Property CurrentValue As Object Implements ITrackedChange.CurrentValue Public Property Status As TrackingStatus = TrackingStatus.Unchecked Public ReadOnly Property HasChanges As Boolean Get Return Status = TrackingStatus.Checked AndAlso DetectChange(CurrentValue) End Get End Property Public Property LastChecked As Date? = Nothing Public Property HasChangedFunc As Func(Of Object, Object, Boolean) Public Function DetectChange(currentValue As Object) As Boolean Return HasChangedFunc(OriginalValue, currentValue) End Function Public Sub AcceptChange() OriginalValue = CurrentValue RejectChange() End Sub Public Sub RejectChange() CurrentValue = Nothing Status = TrackingStatus.Unchecked LastChecked = Nothing End Sub End Class ''' <summary> ''' Provides support for object change tracking ''' </summary> Interface ITrackedChange ReadOnly Property PropertyName As String ReadOnly Property OriginalValue As Object ReadOnly Property CurrentValue As Object End Interface ''' <summary> ''' Provides data for the <see cref=" System.ComponentModel.PropertyChangedEventArgs"/> event ''' </summary> Public Class PropertyChangedTrackedEventArgs : Inherits System.ComponentModel.PropertyChangedEventArgs Public Property OriginalValue As Object Public Property CurrentValue As Object Public Sub New(propertyName As String, originalValue As Object, currentValue As Object) MyBase.New(propertyName) Me.OriginalValue = originalValue Me.CurrentValue = currentValue End Sub End Class ''' <summary> ''' Attribute which allows a property to be ignored from being tracked ''' </summary> Public Class ChangeTrackerIgnoreAttribute : Inherits System.Attribute End Class #Region "Helpers" Protected Function IsTrackedChange(propertyName As String) As Boolean Return Tracked.ContainsKey(propertyName) End Function Protected Function GetTrackedChange(propertyName As String) As TrackedChange Return If(IsTrackedChange(propertyName), CType(Tracked(propertyName), TrackedChange), Nothing) End Function Protected Function GetTrackedChanges() As IEnumerable(Of TrackedChange) Return Tracked.Select(Function(pair) CType(pair.Value, TrackedChange)) End Function Protected Overridable Function GetTrackableProperties() As IEnumerable(Of PropertyInfo) Return Me.GetType().GetProperties() _ .Where(Function(p) Return Not p.DeclaringType.Equals(GetType(ChangeTracker)) _ AndAlso p.CanRead _ AndAlso p.CanWrite _ AndAlso Not p.GetCustomAttributes(Of ChangeTrackerIgnoreAttribute)(False).Any() End Function) End Function Protected Overridable Function GetValue([property] As PropertyInfo) As Object Return [property]?.GetValue(Me, If([property].GetIndexParameters().Count() = 1, New Object() {Nothing}, Nothing)) End Function Protected Overridable Sub SetValue([property] As PropertyInfo, value As Object) If [property] IsNot Nothing AndAlso [property].CanWrite Then [property].SetValue(Me, value) End If End Sub Protected Overridable Function HasValuesChanged(Of T)(originalValue As T, currentValue As T) As Boolean Return Not EqualityComparer(Of T).Default.Equals(originalValue, currentValue) End Function Protected Sub ThrowIfTrackingNotStarted() If Not IsTracking Then Throw New InvalidOperationException("Change tracking has not started. Call 'BeginChanges' to start change tracking") End If End Sub Protected Sub ThrowIfTrackingStarted() If IsTracking Then Throw New InvalidOperationException("Change tracking has already started") End If End Sub #End Region End Class End Namespace ' http://programmingnotes.org/ |
8. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Apr 23, 2022 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates the use of the Utils Namespace ' ============================================================================ Option Strict On Option Explicit On Imports System Imports Utils Public Module Program ' Declare class and inherit ChangeTracker ' Modify the properties you wish to notify changes Public Class Person : Inherits ChangeTracker Private _firstName As String Public Property FirstName As String Get Return _firstName End Get Set(value As String) _firstName = value NotifyPropertyChanged(value) End Set End Property Private _lastName As String Public Property LastName As String Get Return _lastName End Get Set(value As String) _lastName = value NotifyPropertyChanged(value) End Set End Property Private _age As Integer? '<ChangeTrackerIgnore> Public Property Age As Integer? Get Return _age End Get Set(value As Integer?) _age = value NotifyPropertyChanged(value) End Set End Property End Class Sub Main(args As String()) Try ' Declare data Dim person = New Person With { .FirstName = "Kenneth", .LastName = "Perkins", .Age = 31 } ' Set custom event handler function for property changed event AddHandler person.PropertyChanged, AddressOf Person_PropertyChanged ' Required: Changes made to this object will start being ' tracked the moment this function is called person.BeginChanges() Dim changes1 = person.GetChanges() ' Make changes to the object person.FirstName = "Jennifer" person.LastName = "Nguyen" person.Age = 28 ' Get changes made to the object Dim changes2 = person.GetChanges() ' Display the changes DisplayChanges(changes2) ' --- Accept changes --- ' Make changes to the object person.FirstName = "Lynn" person.LastName = "P" person.Age = 10 Dim changes3 = person.GetChanges() ' Accept all the changes made to the object up to ' this point as the source of truth for change tracking person.AcceptChanges() 'Get changes made to the object Dim changes4 = person.GetChanges() ' Display the changes ' Note: No changes will display because the most recent modifications has been accepted DisplayChanges(changes4) ' --- Reject changes --- ' Make changes to the object person.FirstName = "Sole" person.LastName = "P" person.Age = 19 ' Rejects all the changes made to the object up to ' this point and reverts back to the objects state ' before modifications were made person.RejectChanges() ' Get changes made to the object Dim changes5 = person.GetChanges() ' Display the changes ' Note: No changes will display because the most recent modifications has been rejected DisplayChanges(changes5) Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub ' Declare Custom event handler function for the PropertyChanged event Public Sub Person_PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Dim eventArgs = CType(e, ChangeTracker.PropertyChangedTrackedEventArgs) Display($"Event Handler Changes:") Display($" PropertyName: {eventArgs.PropertyName}, OriginalValue: {eventArgs.OriginalValue}, CurrentValue: {eventArgs.CurrentValue}") End Sub Public Sub DisplayChanges(changes As List(Of ChangeTracker.ITrackedChange)) Display($"Changes: {changes.Count}") For Each change In changes Display($" PropertyName: {change.PropertyName}, OriginalValue: {change.OriginalValue}, CurrentValue: {change.CurrentValue}") Next Display("============") End Sub Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Pad Center & Center Align A String Of Fixed Length Using VB.NET
The following is a module with functions which demonstrates how to pad center and center align a string of a fixed length using VB.NET.
The function demonstrated on this page center aligns the characters in a string by padding them on the left and right with a specified character, of a specified total length.
The returned string is padded with as many padding characters needed to reach a length of the specified total width.
The padding character is user defined, but if no padding character is specified, the string is padded using a whitespace (‘ ‘).
1. Pad Center
The example below demonstrates the use of ‘Utils.PadCenter‘ to center align a string of a fixed length.
In this example, the default padding character is used to pad the string, which is a whitespace (‘ ‘).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
' Pad Center Imports Utils ' Declare string Dim original As String = "<-Kenneth->" ' Get padding width Dim width As Integer = 15 ' Display result Debug.Print("Original: '" & original & "'") Debug.Print("Pad Center: '" & original.PadCenter(width) & "'") Debug.Print("Pad Right: '" & original.PadRight(width) & "'") Debug.Print("Pad Left: '" & original.PadLeft(width) & "'") ' expected output: ' Original: '<-Kenneth->' ' Pad Center: ' <-Kenneth-> ' ' Pad Right: '<-Kenneth-> ' ' Pad Left: ' <-Kenneth->' |
2. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Jul 18, 2021 ' Taken From: http://programmingnotes.org/ ' File: Utils.vb ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Namespace Global.Utils Public Module modUtils ''' <summary> ''' Returns a new string that center aligns the characters in a ''' string by padding them on the left and right with a specified ''' character, of a specified total length ''' </summary> ''' <param name="source">The source string</param> ''' <param name="totalWidth">The number of characters to pad the source string</param> ''' <param name="paddingChar">The padding character</param> ''' <returns>The modified source string padded with as many paddingChar ''' characters needed to create a length of totalWidth</returns> <Runtime.CompilerServices.Extension()> Public Function PadCenter(source As String, totalWidth As Integer, Optional paddingChar As Char = " "c) As String Dim spaces = totalWidth - source.Length Dim padLeft = CInt(spaces / 2 + source.Length) Return source.PadLeft(padLeft, paddingChar).PadRight(totalWidth, paddingChar) End Function End Module End Namespace ' http://programmingnotes.org/ |
3. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Jul 18, 2021 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates the use of the Utils Namespace ' ============================================================================ Option Strict On Option Explicit On Imports System Imports Utils Public Module Program Sub Main(args As String()) Try ' Declare string Dim original As String = "<-Kenneth->" ' Get padding width Dim width As Integer = 15 ' Display result Display("Original: '" & original & "'") Display("Pad Center: '" & original.PadCenter(width) & "'") Display("Pad Right: '" & original.PadRight(width) & "'") Display("Pad Left: '" & original.PadLeft(width) & "'") Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Create Multiple Tasks With Maximum Concurrency Using VB.NET
The following is a module with functions which demonstrates how to create multiple tasks with maximum concurrency using VB.NET.
The examples demonstrated on this page uses System.Threading.Tasks.Task to start and run tasks. They also use System.Threading.SemaphoreSlim to limit the number of tasks that can run concurrently.
The examples on this page demonstrates how to start and run multiple tasks with a maximum concurrency. It also demonstrates how to start and run multiple tasks with a return value.
1. Task – Maximum Concurrency
The example below demonstrates how to start and run multiple tasks with a maximum concurrency. For example purposes, the tasks do not return a value.
The functions shown in the example below are called asynchronously, but they can also be called synchronously.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
' Task - Maximum Concurrency Dim concurrentTasks = 5 Dim semaphore = New System.Threading.SemaphoreSlim(concurrentTasks, concurrentTasks) Dim tasks = New List(Of System.Threading.Tasks.Task) For count = 1 To 20 Dim taskNumber = count ' Blocks execution until another task can be started. ' This function also accepts a timeout in milliseconds Await semaphore.WaitAsync() ' Start a task Dim task = System.Threading.Tasks.Task.Run(Async Function() ' Execute long running code Try Debug.Print($"Task #{taskNumber} starting...") Await System.Threading.Tasks.Task.Delay(5000) Debug.Print($" - Task #{taskNumber} completed!") Catch ex As Exception Throw Finally ' Signal that the task is completed ' so another task can start semaphore.Release() End Try End Function) tasks.Add(task) Next Debug.Print($"Waiting for tasks to complete") ' Wait for all tasks to complete Await System.Threading.Tasks.Task.WhenAll(tasks.ToArray) Debug.Print($"All tasks completed!") ' example output: ' Task #1 starting... ' Task #2 starting... ' Task #3 starting... ' Task #4 starting... ' Task #5 starting... ' - Task #1 completed! ' - Task #2 completed! ' Task #6 starting... ' Task #7 starting... ' - Task #4 completed! ' - Task #3 completed! ' - Task #5 completed! ' Task #8 starting... ' Task #9 starting... ' Task #10 starting... ' - Task #7 completed! ' - Task #6 completed! ' Task #11 starting... ' Task #12 starting... ' - Task #9 completed! ' - Task #10 completed! ' Task #13 starting... ' Task #14 starting... ' - Task #8 completed! ' Task #15 starting... ' - Task #12 completed! ' - Task #11 completed! ' Task #16 starting... ' Task #17 starting... ' - Task #14 completed! ' - Task #13 completed! ' - Task #15 completed! ' Task #19 starting... ' Waiting for tasks to complete ' Task #18 starting... ' Task #20 starting... ' - Task #17 completed! ' - Task #16 completed! ' - Task #19 completed! ' - Task #20 completed! ' - Task #18 completed! ' All tasks completed! |
2. Task – Maximum Concurrency – Return Value
The example below demonstrates how to start and run multiple tasks with a maximum concurrency. In this example, a value is returned and retrieved from the tasks
The functions shown in the example below are called asynchronously, but they can also be called synchronously.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
' Task - Maximum Concurrency - Return Value Public Class Part Public Property PartName As String Public Property PartId As Integer End Class Dim concurrentTasks = 5 Dim semaphore = New System.Threading.SemaphoreSlim(concurrentTasks, concurrentTasks) Dim tasks = New List(Of System.Threading.Tasks.Task(Of Part)) For count = 1 To 20 Dim taskNumber = count ' Blocks execution until another task can be started. ' This function also accepts a timeout in milliseconds Await semaphore.WaitAsync() ' Start a task Dim task = System.Threading.Tasks.Task.Run(Async Function() ' Execute long running code Try Debug.Print($"Task #{taskNumber} starting...") Await System.Threading.Tasks.Task.Delay(5000) Debug.Print($" - Task #{taskNumber} completed!") ' Return result Return New Part With { .PartId = taskNumber, .PartName = $"Part #{taskNumber}" } Catch ex As Exception Throw Finally ' Signal that the task is completed ' so another task can start semaphore.Release() End Try End Function) tasks.Add(task) Next Debug.Print($"Waiting for tasks to complete") ' Wait for all tasks to complete Await System.Threading.Tasks.Task.WhenAll(tasks.ToArray) Debug.Print($"All tasks completed!") Debug.Print("") ' Get the results For Each task In tasks Dim part = task.Result Debug.Print($"Id: {part.PartId}, Name: {part.PartName}") Next ' example output: ' Task #1 starting... ' Task #2 starting... ' Task #3 starting... ' Task #4 starting... ' Task #5 starting... ' - Task #3 completed! ' - Task #2 completed! ' - Task #5 completed! ' - Task #1 completed! ' Task #8 starting... ' Task #7 starting... ' Task #6 starting... ' - Task #4 completed! ' Task #9 starting... ' Task #10 starting... ' - Task #8 completed! ' Task #11 starting... ' - Task #7 completed! ' Task #12 starting... ' - Task #6 completed! ' Task #13 starting... ' - Task #10 completed! ' - Task #9 completed! ' Task #14 starting... ' Task #15 starting... ' - Task #11 completed! ' Task #16 starting... ' - Task #12 completed! ' Task #17 starting... ' - Task #13 completed! ' Task #18 starting... ' - Task #15 completed! ' - Task #14 completed! ' Task #19 starting... ' Waiting for tasks to complete ' Task #20 starting... ' - Task #16 completed! ' - Task #17 completed! ' - Task #18 completed! ' - Task #19 completed! ' - Task #20 completed! ' All tasks completed! ' ' Id: 1, Name: Part #1 ' Id: 2, Name: Part #2 ' Id: 3, Name: Part #3 ' Id: 4, Name: Part #4 ' Id: 5, Name: Part #5 ' Id: 6, Name: Part #6 ' Id: 7, Name: Part #7 ' Id: 8, Name: Part #8 ' Id: 9, Name: Part #9 ' Id: 10, Name: Part #10 ' Id: 11, Name: Part #11 ' Id: 12, Name: Part #12 ' Id: 13, Name: Part #13 ' Id: 14, Name: Part #14 ' Id: 15, Name: Part #15 ' Id: 16, Name: Part #16 ' Id: 17, Name: Part #17 ' Id: 18, Name: Part #18 ' Id: 19, Name: Part #19 ' Id: 20, Name: Part #20 |
3. More Examples
Below is a full example of the process demonstrated on this page!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Dec 4, 2020 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates creating a task pool ' ============================================================================ Option Strict On Option Explicit On Imports System Public Module Program Public Class Part Public Property PartName As String Public Property PartId As Integer End Class Sub Main(args As String()) Try 'TaskSub.Wait() TaskFunction.Wait() Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub Public Async Function TaskFunction() As Task(Of List(Of Part)) Dim concurrentTasks = 5 Dim semaphore = New System.Threading.SemaphoreSlim(concurrentTasks, concurrentTasks) Dim tasks = New List(Of System.Threading.Tasks.Task(Of Part)) For count = 1 To 20 Dim taskNumber = count ' Blocks execution until another task can be started. ' This function also accepts a timeout in milliseconds Await semaphore.WaitAsync() ' Start a task Dim task = System.Threading.Tasks.Task.Run(Async Function() ' Execute long running code Try Display($"Task #{taskNumber} starting...") Await System.Threading.Tasks.Task.Delay(5000) Display($" - Task #{taskNumber} completed!") Return New Part With { .PartId = taskNumber, .PartName = $"Part #{taskNumber}" } Catch ex As Exception Throw Finally ' Signal that the task is completed ' so another task can start semaphore.Release() End Try End Function) tasks.Add(task) Next Display($"Waiting for tasks to complete") ' Wait for all tasks to complete Await System.Threading.Tasks.Task.WhenAll(tasks.ToArray) Display($"All tasks completed!") Display("") ' Get the results For Each task In tasks Dim part = task.Result Display($"Id: {part.PartId}, Name: {part.PartName}") Next Return tasks.Select(Function(task) task.Result).ToList End Function Public Async Function TaskSub() As Task Dim concurrentTasks = 5 Dim semaphore = New System.Threading.SemaphoreSlim(concurrentTasks, concurrentTasks) Dim tasks = New List(Of System.Threading.Tasks.Task) For count = 1 To 20 Dim taskNumber = count ' Blocks execution until another task can be started. ' This function also accepts a timeout in milliseconds Await semaphore.WaitAsync() ' Start a task Dim task = System.Threading.Tasks.Task.Run(Async Function() ' Execute long running code Try Display($"Task #{taskNumber} starting...") Await System.Threading.Tasks.Task.Delay(5000) Display($" - Task #{taskNumber} completed!") Catch ex As Exception Throw Finally ' Signal that the task is completed ' so another task can start semaphore.Release() End Try End Function) tasks.Add(task) Next Display($"Waiting for tasks to complete") ' Wait for all tasks to complete Await System.Threading.Tasks.Task.WhenAll(tasks.ToArray) Display($"All tasks completed!") End Function Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Convert Bytes To Kilobytes, Megabytes, Gigabytes, Terabytes Using VB.NET
The following is a module with functions which demonstrates how to convert bytes to decimal formats like kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, zettabytes, and yottabytes, as well as binary formats like kibibytes, mebibytes, gibibytes, tebibytes, pebibytes, exbibytes, zebibytes, and yobibytes using VB.NET.
The function demonstrated on this page follows the IEC standard, which means:
• 1 kilobyte = 1000 bytes (Decimal)
• 1 kibibyte = 1024 bytes (Binary)
This function allows you to convert bytes to a measurement unit, a measurement unit to bytes, and allows to convert from one measurement unit to another measurement unit.
1. Convert Bytes To Measurement Unit
The example below demonstrates the use of ‘Utils.Bytes.FromTo‘ to convert bytes to a measurement unit.
The optional function parameter allows you to specify the decimal places.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
' Convert Bytes To Measurement Unit ' Declare values to convert Dim values = {2287879, 536870912, 1073741824} ' Convert values For Each value In values ' Convert bytes to megabyte Dim mb = Utils.Bytes.FromTo(Utils.Bytes.Unit.Byte, value, Utils.Bytes.Unit.Megabyte) ' Convert bytes to mebibyte Dim mib = Utils.Bytes.FromTo(Utils.Bytes.Unit.Byte, value, Utils.Bytes.Unit.Mebibyte) ' Display the converted values Debug.Print($"Bytes: {value}, Megabyte: {mb}, Mebibyte: {mib}") Next ' expected output: ' Bytes: 2287879, Megabyte: 2.287879, Mebibyte: 2.18189144134521484375 ' Bytes: 536870912, Megabyte: 536.870912, Mebibyte: 512 ' Bytes: 1073741824, Megabyte: 1073.741824, Mebibyte: 1024 |
2. Convert Measurement Unit To Bytes
The example below demonstrates the use of ‘Utils.Bytes.FromTo‘ to convert a measurement unit to bytes.
The optional function parameter allows you to specify the decimal places.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
' Convert Measurement Unit To Bytes ' Declare values to convert Dim values = {1, 0.5D, 10.75D} ' Convert values For Each value In values ' Convert gibibyte to byte Dim bytes = Utils.Bytes.FromTo(Utils.Bytes.Unit.Gibibyte, value, Utils.Bytes.Unit.Byte) ' Display the converted values Debug.Print($"Gibibyte: {value}, Bytes: {bytes}") Next ' expected output: ' Gibibyte: 1, Bytes: 1073741824 ' Gibibyte: 0.5, Bytes: 536870912.0 ' Gibibyte: 10.75, Bytes: 11542724608.00 |
3. Convert Measurement Unit To Measurement Unit
The example below demonstrates the use of ‘Utils.Bytes.FromTo‘ to convert a measurement unit to another measurement unit.
The optional function parameter allows you to specify the decimal places.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
' Convert Measurement Unit To Measurement Unit ' Declare values to convert Dim values = {1991, 1987, 28.31D, 19.22D} ' Convert values For Each value In values ' Convert value from one unit to another Dim size = Utils.Bytes.FromTo(Utils.Bytes.Unit.Gigabyte, value, Utils.Bytes.Unit.Terabyte) ' Display the converted values Debug.Print($"Gigabyte: {value}, Terabyte: {size}") Next ' expected output: ' Gigabyte: 1991, Terabyte: 1.991 ' Gigabyte: 1987, Terabyte: 1.987 ' Gigabyte: 28.31, Terabyte: 0.02831 ' Gigabyte: 19.22, Terabyte: 0.01922 |
4. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Dec 3, 2020 ' Taken From: http://programmingnotes.org/ ' File: Utils.vb ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Namespace Global.Utils Namespace Bytes Public Module modBytes Public Enum Unit [Byte] ' Decimal Kilobyte Megabyte Gigabyte Terabyte Petabyte Exabyte Zettabyte Yottabyte ' Binary Kibibyte Mebibyte Gibibyte Tebibyte Pebibyte Exbibyte Zebibyte Yobibyte End Enum ''' <summary> ''' Converts a measurement 'Unit' to another measurement 'Unit' ''' </summary> ''' <param name="unitFrom">The measurement unit converting from</param> ''' <param name="sizeFrom">The size of the 'from' measurement unit</param> ''' <param name="unitTo">The measurement unit to convert to</param> ''' <param name="decimalPlaces">The decimal places to round to</param> ''' <returns>The value converted to the specified measurement unit</returns> Public Function FromTo(unitFrom As Unit, sizeFrom As Decimal, unitTo As Unit _ , Optional decimalPlaces As Integer? = Nothing) As Decimal Dim result = sizeFrom If unitFrom <> unitTo Then If unitFrom = Unit.Byte Then result = ConvertTo(unitTo, sizeFrom, decimalPlaces) ElseIf unitTo = Unit.Byte Then result = ConvertFrom(unitFrom, sizeFrom, decimalPlaces) Else result = ConvertTo(unitTo, ConvertFrom(unitFrom, sizeFrom), decimalPlaces) End If End If Return result End Function Private Enum Conversion From [To] End Enum ' Converts bytes to a measurement unit Private Function ConvertTo(unit As Unit, bytes As Decimal _ , Optional decimalPlaces As Integer? = Nothing) As Decimal Return Convert(Conversion.To, bytes, unit, decimalPlaces) End Function ' Converts a measurement unit to bytes Private Function ConvertFrom(unit As Unit, bytes As Decimal _ , Optional decimalPlaces As Integer? = Nothing) As Decimal Return Convert(Conversion.From, bytes, unit, decimalPlaces) End Function Private Function Convert(operation As Conversion, bytes As Decimal, unit As Unit _ , decimalPlaces As Integer?) As Decimal ' Get the unit type definition Dim definition = GetDefinition(unit) If definition Is Nothing Then Throw New ArgumentException($"Unknown unit type: {unit}", NameOf(unit)) End If ' Get the unit value Dim value = definition.Value ' Calculate the result Dim result = If(operation = Conversion.To, bytes / value, bytes * value) If decimalPlaces.HasValue Then result = Math.Round(result, decimalPlaces.Value, MidpointRounding.AwayFromZero) End If Return result End Function Public Enum Prefix [Decimal] Binary End Enum Public Class Definition Public Property Prefix As Prefix Public Property OrderOfMagnitude As Integer Public ReadOnly Property Multiple As Decimal Get Return If(Prefix = Prefix.Decimal, 1000, 1024) End Get End Property Public ReadOnly Property Value As Decimal Get Return CDec(Math.Pow(Multiple, OrderOfMagnitude)) End Get End Property End Class Public Function GetDefinition(unit As Unit) As Definition Dim definitions = GetDefinitions() Return If(definitions.ContainsKey(unit), definitions(unit), Nothing) End Function Public Function GetDefinitions() As Dictionary(Of Unit, Definition) ' Create and add definitions Static definitions As Dictionary(Of Unit, Definition) If definitions Is Nothing Then definitions = New Dictionary(Of Unit, Definition) ' Place units in order of magnitude ' Decimal units Dim decimals = { Unit.Kilobyte, Unit.Megabyte, Unit.Gigabyte, Unit.Terabyte _ , Unit.Petabyte, Unit.Exabyte, Unit.Zettabyte, Unit.Yottabyte } ' Binary units Dim binary = { Unit.Kibibyte, Unit.Mebibyte, Unit.Gibibyte, Unit.Tebibyte _ , Unit.Pebibyte, Unit.Exbibyte, Unit.Zebibyte, Unit.Yobibyte } AddDefinitions(definitions, Prefix.Decimal, decimals) AddDefinitions(definitions, Prefix.Binary, binary) End If Return definitions End Function Private Sub AddDefinitions(definitions As Dictionary(Of Unit, Definition) _ , prefix As Prefix, units As IEnumerable(Of Unit)) For index = 0 To units.Count - 1 Dim unit = units(index) If Not definitions.ContainsKey(unit) Then definitions.Add(unit, New Definition With { .Prefix = prefix, .OrderOfMagnitude = index + 1 }) End If Next End Sub End Module End Namespace End Namespace ' http://programmingnotes.org/ |
5. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Dec 3, 2020 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates the use of the Utils Namespace ' ============================================================================ Option Strict On Option Explicit On Imports System Public Module Program Sub Main(args As String()) Try ' Declare values to convert Dim values = {2287879, 536870912, 1073741824} ' Convert values For Each value In values ' Convert bytes to megabyte Dim mb = Utils.Bytes.FromTo(Utils.Bytes.Unit.Byte, value, Utils.Bytes.Unit.Megabyte) ' Convert bytes to mebibyte Dim mib = Utils.Bytes.FromTo(Utils.Bytes.Unit.Byte, value, Utils.Bytes.Unit.Mebibyte) ' Display the converted values Display($"Bytes: {value}, Megabyte: {mb}, Mebibyte: {mib}") Next Display("") ' Declare values to convert Dim values2 = {1, 0.5D, 10.75D} ' Convert values For Each value In values2 ' Convert gibibyte to byte Dim bytes = Utils.Bytes.FromTo(Utils.Bytes.Unit.Gibibyte, value, Utils.Bytes.Unit.Byte) ' Display the converted values Display($"Gibibyte: {value}, Bytes: {bytes}") Next Display("") ' Declare values to convert Dim values3 = {1991, 1987, 28.31D, 19.22D} ' Convert values For Each value In values3 ' Convert value from one unit to another Dim size = Utils.Bytes.FromTo(Utils.Bytes.Unit.Gigabyte, value, Utils.Bytes.Unit.Terabyte) ' Display the converted values Display($"Gigabyte: {value}, Terabyte: {size}") Next Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Parse A Delimited CSV File Using VB.NET
The following is a module with functions which demonstrates how to parse a delimited CSV file using VB.NET.
The function demonstrated on this page uses FileIO.TextFieldParser to parse values in a CSV file.
This function parses a CSV file and returns its results as a List. Each List index represents a line in the CSV file, with each item in the list representing a record contained on that line.
1. Parse CSV File
The example below demonstrates the use of ‘Utils.ParseCsv‘ to parse a CSV file and return its results as a List.
The optional function parameter allows you to specify the delimiters. Default delimiter is a comma (,).
Sample CSV used in this example is the following:
1 2 3 4 5 6 |
Kenneth,Perkins,120 jefferson st.,Riverside, NJ, 08075 Jack,McGinnis,220 hobo Av.,Phila, PA,09119 "Jennifer ""Da Man""",Repici,120 Jefferson St.,Riverside, NJ,08075 Stephen,Tyler,"7452 Terrace ""At the Plaza"" road",SomeTown,SD, 91234 ,Blankman,,SomeTown, SD, 00298 "Joan ""the bone"", Anne",Jet,"9th, at Terrace plc",Desert City,CO,00123 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
' Parse CSV File ' Read file into byte array Dim fileBytes As Byte() ' Parse the contents of the file into a list Dim fileContents = Utils.ParseCsv(fileBytes) ' Display the contents of the file For lineIndex = 0 To fileContents.Count - 1 Dim line = fileContents(lineIndex) Debug.Print($"Line #{lineIndex + 1}") For Each item In line Debug.Print($" Item: {item}") Next Next ' expected output: ' Line #1 ' Item: Kenneth ' Item: Perkins ' Item: 120 jefferson st. ' Item: Riverside ' Item: NJ ' Item: 08075 ' Line #2 ' Item: Jack ' Item: McGinnis ' Item: 220 hobo Av. ' Item: Phila ' Item: PA ' Item: 09119 ' Line #3 ' Item: Jennifer "Da Man" ' Item: Repici ' Item: 120 Jefferson St. ' Item: Riverside ' Item: NJ ' Item: 08075 ' Line #4 ' Item: Stephen ' Item: Tyler ' Item: 7452 Terrace "At the Plaza" road ' Item: SomeTown ' Item: SD ' Item: 91234 ' Line #5 ' Item: ' Item: Blankman ' Item: ' Item: SomeTown ' Item: SD ' Item: 00298 ' Line #6 ' Item: Joan "the bone", Anne ' Item: Jet ' Item: 9th, at Terrace plc ' Item: Desert City ' Item: CO ' Item: 00123 |
2. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Dec 2, 2020 ' Taken From: http://programmingnotes.org/ ' File: Utils.vb ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Namespace Global.Utils Public Module modUtils ''' <summary> ''' Parses a Csv file and returns its results as a List. ''' Each List index represents a line in the Csv file, with each ''' item in the list representing a record contained on that line. ''' </summary> ''' <param name="fileBytes">The Csv file as a byte array</param> ''' <param name="delimiters">The Csv data delimiter</param> ''' <returns>The file contents as a List</returns> Public Function ParseCsv(fileBytes As Byte() _ , Optional delimiters As String = ",") As List(Of List(Of String)) Dim results = New List(Of List(Of String)) Using stream = New System.IO.MemoryStream(fileBytes) Using parser = New Microsoft.VisualBasic.FileIO.TextFieldParser(stream) parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited parser.Delimiters = delimiters.Select(Function(letter) letter.ToString).ToArray parser.HasFieldsEnclosedInQuotes = True ' Parse each line in the file While Not parser.EndOfData Dim currentLine = parser.ReadFields results.Add(currentLine.ToList) End While End Using End Using Return results End Function End Module End Namespace ' http://programmingnotes.org/ |
3. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Dec 2, 2020 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates the use of the Utils Namespace ' ============================================================================ Option Strict On Option Explicit On Imports System Public Module Program Sub Main(args As String()) Try ' Read file into byte array Dim fileBytes As Byte() ' Parse the contents of the file into a list Dim fileContents = Utils.ParseCsv(fileBytes) ' Display the contents of the file For lineIndex = 0 To fileContents.Count - 1 Dim line = fileContents(lineIndex) Display($"Line #{lineIndex + 1}") For Each item In line Display($" Item: {item}") Next Next Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Round A Number To The Nearest X Using VB.NET
The following is a module with functions which demonstrates how to round a number to the nearest X using VB.NET.
This function has the ability to either round a number to the nearest amount, always round up, or always round down. For example, when dealing with money, this is good for rounding a dollar amount to the nearest 5 cents.
1. Round – Nearest
The example below demonstrates the use of ‘Utils.RoundAmount‘ to round a number to the nearest 5 cents.
The optional function parameter determines they type of rounding to perform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
' Round - Nearest ' Declare values to round Dim values = New Decimal() {19.28D, 31.22D, 19.91D, 19.87D, 0.05D} ' Declare step amount Dim stepAmount = 0.05D ' Round to nearest amount For Each value In values Debug.Print($"Value: {value}, Rounded: {Utils.RoundAmount(value, stepAmount)}") Next ' expected output: ' Value: 19.28, Rounded: 19.3 ' Value: 31.22, Rounded: 31.2 ' Value: 19.91, Rounded: 19.9 ' Value: 19.87, Rounded: 19.85 ' Value: 0.05, Rounded: 0.05 |
2. Round – Up
The example below demonstrates the use of ‘Utils.RoundAmount‘ to always round a number up to the nearest 5 cents.
The optional function parameter determines they type of rounding to perform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
' Round - Up ' Declare values to round Dim values = New Decimal() {19.28D, 31.22D, 19.91D, 19.87D, 0.05D} ' Declare step amount Dim stepAmount = 0.05D ' Round up to nearest amount For Each value In values Debug.Print($"Value: {value}, Rounded: {Utils.RoundAmount(value, stepAmount, Utils.RoundType.Up)}") Next ' expected output: ' Value: 19.28, Rounded: 19.3 ' Value: 31.22, Rounded: 31.25 ' Value: 19.91, Rounded: 19.95 ' Value: 19.87, Rounded: 19.9 ' Value: 0.05, Rounded: 0.05 |
3. Round – Down
The example below demonstrates the use of ‘Utils.RoundAmount‘ to always round a number down to the nearest 5 cents.
The optional function parameter determines they type of rounding to perform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
' Round - Down ' Declare values to round Dim values = New Decimal() {19.28D, 31.22D, 19.91D, 19.87D, 0.05D} ' Declare step amount Dim stepAmount = 0.05D ' Round down to nearest amount For Each value In values Debug.Print($"Value: {value}, Rounded: {Utils.RoundAmount(value, stepAmount, Utils.RoundType.Down)}") Next ' expected output: ' Value: 19.28, Rounded: 19.25 ' Value: 31.22, Rounded: 31.2 ' Value: 19.91, Rounded: 19.9 ' Value: 19.87, Rounded: 19.85 ' Value: 0.05, Rounded: 0.05 |
4. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Dec 1, 2020 ' Taken From: http://programmingnotes.org/ ' File: Utils.vb ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Namespace Global.Utils Public Module modUtils Public Enum RoundType Nearest Up Down End Enum ''' <summary> ''' Rounds a number to the nearest X ''' </summary> ''' <param name="value">The value to round</param> ''' <param name="stepAmount">The amount to round the value by</param> ''' <param name="type">The type of rounding to perform</param> ''' <returns>The value rounded by the step amount and type</returns> Public Function RoundAmount(value As Decimal, stepAmount As Decimal _ , Optional type As RoundType = RoundType.Nearest) As Decimal Dim inverse = 1 / stepAmount Dim dividend = value * inverse Select Case type Case RoundType.Nearest dividend = Math.Round(dividend) Case RoundType.Up dividend = Math.Ceiling(dividend) Case RoundType.Down dividend = Math.Floor(dividend) Case Else Throw New ArgumentException($"Unknown type: {type}", NameOf(type)) End Select Dim result = dividend / inverse Return result End Function End Module End Namespace ' http://programmingnotes.org/ |
5. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Dec 1, 2020 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates the use of the Utils Namespace ' ============================================================================ Option Strict On Option Explicit On Imports System Public Module Program Sub Main(args As String()) Try ' Declare values to round Dim values = New Decimal() {19.28D, 31.22D, 19.91D, 19.87D, 0.05D} ' Declare step amount Dim stepAmount = 0.05D ' Round to nearest amount For Each value In values Display($"Value: {value}, Rounded: {Utils.RoundAmount(value, stepAmount)}") Next Display("") ' Round up to nearest amount For Each value In values Display($"Value: {value}, Rounded: {Utils.RoundAmount(value, stepAmount, Utils.RoundType.Up)}") Next Display("") ' Round down to nearest amount For Each value In values Display($"Value: {value}, Rounded: {Utils.RoundAmount(value, stepAmount, Utils.RoundType.Down)}") Next Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Replace A Letter With Its Alphabet Position Using VB.NET
The following is a module with functions which demonstrates how to replace a letter with its alphabet position using VB.NET.
1. Replace With Alphabet Position
The example below demonstrates the use of ‘Utils.GetAlphabetPosition‘ to replace a letter with its alphabet position.
1 2 3 4 5 6 7 8 9 10 |
' Replace With Alphabet Position ' Get alphabet position Dim result = Utils.GetAlphabetPosition("The sunset sets at twelve o' clock.") ' Display the results Debug.Print(String.Join(" ", result)) ' expected output: ' 20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11 |
2. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Nov 30, 2020 ' Taken From: http://programmingnotes.org/ ' File: Utils.vb ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Namespace Global.Utils Public Module modUtils ''' <summary> ''' Gets the alphabet position of each character in a string ''' </summary> ''' <param name="text">The text to get the position</param> ''' <returns>The alphabet position of each character</returns> Public Function GetAlphabetPosition(text As String) As List(Of Integer) Dim alphabet = "abcdefghijklmnopqrstuvwxyz" Dim result = New List(Of Integer) For Each letter In text.ToLower Dim index = alphabet.IndexOf(letter) If index > -1 Then result.Add(index + 1) End If Next Return result End Function End Module End Namespace ' http://programmingnotes.org/ |
3. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Nov 30, 2020 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates the use of the Utils Namespace ' ============================================================================ Option Strict On Option Explicit On Imports System Public Module Program Sub Main(args As String()) Try Dim result = Utils.GetAlphabetPosition("The sunset sets at twelve o' clock.") Display(String.Join(" ", result)) Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Generate A Random String Of A Specified Length Using VB.NET
The following is a module with functions which demonstrates how to generate a random code of a specified length using VB.NET.
The function demonstrated on this page has the ability to generate random strings that contains only letters, only numerical digits, or alphanumeric strings.
1. Random Code – Alphabetical
The example below demonstrates the use of ‘Utils.GetRandomCode‘ to generate a code of a specified length that contains only letters.
The optional function parameter determines the type of code that is generated.
1 2 3 4 5 6 7 8 9 10 |
' Random Code - Alphabetical ' Generate code containing only letters Dim letters = Utils.GetRandomCode(5) ' Display the code Debug.Print($"Code: {letters}") ' example output: ' Code: DWhxO |
2. Random Code – Numeric
The example below demonstrates the use of ‘Utils.GetRandomCode‘ to generate a code of a specified length that contains only digits.
The optional function parameter determines the type of code that is generated.
1 2 3 4 5 6 7 8 9 10 |
' Random Code - Numeric ' Generate code containing only digits Dim numeric = Utils.GetRandomCode(7, Utils.CodeType.Numeric) ' Display the code Debug.Print($"Code: {numeric}") ' example output: ' Code: 6407422 |
3. Random Code – Alphanumeric
The example below demonstrates the use of ‘Utils.GetRandomCode‘ to generate a code of a specified length that is alphanumeric.
The optional function parameter determines the type of code that is generated.
1 2 3 4 5 6 7 8 9 10 |
' Random Code - Alphanumeric ' Generate alphanumeric code Dim alphaNumeric = Utils.GetRandomCode(10, Utils.CodeType.AlphaNumeric) ' Display the code Debug.Print($"Code: {alphaNumeric}") ' example output: ' Code: C3G9mt9wf8 |
4. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Nov 30, 2020 ' Taken From: http://programmingnotes.org/ ' File: Utils.vb ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Namespace Global.Utils Public Module modUtils Public Enum CodeType ''' <summary> ''' Code contains only letters ''' </summary> Alphabetical ''' <summary> ''' Code contains only digits ''' </summary> Numeric ''' <summary> ''' Code contains letters and digits ''' </summary> AlphaNumeric End Enum ''' <summary> ''' Generates a random string of a specified length according to the type ''' </summary> ''' <param name="length">The length of the random string</param> ''' <param name="type">The type of string to generate</param> ''' <returns>The random string according to the type</returns> Public Function GetRandomCode(length As Integer _ , Optional type As CodeType = CodeType.Alphabetical) As String Dim digits = "0123456789" Dim alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" Dim source = String.Empty Select Case type Case CodeType.Alphabetical source = alphabet Case CodeType.Numeric source = digits Case CodeType.AlphaNumeric source = alphabet + digits Case Else Throw New ArgumentException($"Unknown type: {type}", NameOf(type)) End Select Dim r = New Random Dim result = New System.Text.StringBuilder While result.Length < length result.Append(source(r.Next(0, source.Length))) End While Return result.ToString End Function End Module End Namespace ' http://programmingnotes.org/ |
5. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Nov 30, 2020 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates the use of the Utils Namespace ' ============================================================================ Option Strict On Option Explicit On Imports System Public Module Program Sub Main(args As String()) Try ' Generate code containing only letters Dim letters = Utils.GetRandomCode(5) ' Display the code Display($"Code: {letters}") Display("") ' Generate code containing only digits Dim numeric = Utils.GetRandomCode(7, Utils.CodeType.Numeric) ' Display the code Display($"Code: {numeric}") Display("") ' Generate alphanumeric code Dim alphaNumeric = Utils.GetRandomCode(10, Utils.CodeType.AlphaNumeric) ' Display the code Display($"Code: {alphaNumeric}") Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Get A List Of Files At A Given Path Directory Using VB.NET
The following is a module with functions which demonstrates how to get a list of files at a given directory path using VB.NET.
The function demonstrated on this page returns a list of System.IO.FileInfo, which contains information about the files in the given directory.
1. Get Files In Directory
The example below demonstrates the use of ‘Utils.GetFilesInDirectory‘ to get a list of files at a given path directory.
The optional function parameter lets you specify the search option. This lets you specify whether to limit the search to just the current directory, or expand the search to the current directory and all subdirectories when searching for files.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
' Get Files In Directory ' Declare directory path Dim directory = "C:\Users\Name\Desktop" ' Get files at the specified directory Dim files = Utils.GetFilesInDirectory(directory) ' Display info about the files For Each file In files Debug.Print($"File: {file.FullName} - Last Modified: {file.LastWriteTime}") Next ' example output: ' File: C:\Users\Name\Desktop\text.txt - Last Modified: 10/7/2020 12:47:56 PM ' File: C:\Users\Name\Desktop\image.png - Last Modified: 9/4/2020 8:36:25 PM ' File: C:\Users\Name\Desktop\document.docx - Last Modified: 3/7/2018 9:26:19 PM |
2. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Nov 30, 2020 ' Taken From: http://programmingnotes.org/ ' File: Utils.vb ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Namespace Global.Utils Public Module modUtils ''' <summary> ''' Returns a list of <see cref="System.IO.FileInfo"/> of the files ''' in the given directory ''' </summary> ''' <param name="directory">The relative or absolute path to the directory to search</param> ''' <param name="searchOption">The file search option</param> ''' <returns>A list of <see cref="System.IO.FileInfo"/> in the given directory</returns> Public Function GetFilesInDirectory(directory As String _ , Optional searchOption As System.IO.SearchOption = System.IO.SearchOption.TopDirectoryOnly) As List(Of System.IO.FileInfo) Return System.IO.Directory.GetFiles(directory, "*", searchOption) _ .Select(Function(fileName) New System.IO.FileInfo(fileName)).ToList End Function End Module End Namespace ' http://programmingnotes.org/ |
3. More Examples
Below are more examples demonstrating the use of the ‘Utils‘ Namespace. Don’t forget to include the module when running the examples!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Nov 30, 2020 ' Taken From: http://programmingnotes.org/ ' File: Program.vb ' Description: The following demonstrates the use of the Utils Namespace ' ============================================================================ Option Strict On Option Explicit On Imports System Public Module Program Sub Main(args As String()) Try ' Declare directory path Dim directory = "C:\path\to\directory" ' Get files at the specified directory Dim files = Utils.GetFilesInDirectory(directory) ' Display info about the files For Each file In files Display($"File: {file.FullName} - Last Modified: {file.LastWriteTime}") Next Catch ex As Exception Display(ex.ToString) Finally Console.ReadLine() End Try End Sub Public Sub Display(message As String) Console.WriteLine(message) Debug.Print(message) End Sub End Module ' http://programmingnotes.org/ |
QUICK NOTES:
The highlighted lines are sections of interest to look out for.
The code is heavily commented, so no further insight is necessary. If you have any questions, feel free to leave a comment below.
VB.NET || How To Get The Computer & User Client IP Address Using VB.NET
The following is a module with functions which demonstrates how to get the computers and user client request IPv4 IP address using VB.NET.
The function demonstrated on this page returns the IPv4 address of the calling user. When under a web environment, it returns the clients System.Web.HttpContext.Current.Request IP address, otherwise it returns the IP address of the local machine (i.e: server) if there is no request.
The following function uses System.Web to determine the IP address of the client.
Note: To use the function in this module, make sure you have a reference to ‘System.Web‘ in your project.
One way to do this is, in your Solution Explorer (where all the files are shown with your project), right click the ‘References‘ folder, click ‘Add Reference‘, then type ‘System.Web‘ in the search box, and add the reference titled System.Web in the results Tab.
1. Get IP Address
The example below demonstrates the use of ‘Utils.GetIPv4Address‘ to get the IPv4 address of the calling user.
1 2 3 4 5 6 7 8 9 |
' Get IP Address ' Get IP address of the current user Dim ipAddress = Utils.GetIPv4Address Debug.Print($"IP Address: {ipAddress}") ' example output: ' IP Address: 192.168.0.5 |
2. Utils Namespace
The following is the Utils Namespace. Include this in your project to start using!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
' ============================================================================ ' Author: Kenneth Perkins ' Date: Nov 29, 2020 ' Taken From: http://programmingnotes.org/ ' File: Utils.vb ' Description: Handles general utility functions ' ============================================================================ Option Strict On Option Explicit On Namespace Global.Utils Public Module modUtils ''' <summary> ''' Returns the IPv4 address of the calling user. When under a web ''' environment, returns the <see cref="System.Web.HttpRequest"/> ''' IP address, otherwise returns the IP address of the local machine ''' </summary> ''' <returns>The IPv4 address of the calling user</returns> Public Function GetIPv4Address() As String Dim ipAddress = String.Empty ' Get client ip address If System.Web.HttpContext.Current IsNot Nothing _ AndAlso System.Web.HttpContext.Current.Request IsNot Nothing Then ' Get client ip address using ServerVariables Dim request = System.Web.HttpContext.Current.Request ipAddress = request.ServerVariables("HTTP_X_FORWARDED_FOR") If Not String.IsNullOrEmpty(ipAddress) Then Dim addresses = ipAddress.Split(",".ToCharArray, StringSplitOptions.RemoveEmptyEntries) If addresses.Length > 0 Then ipAddress = addresses(0) End If End If If String.IsNullOrEmpty(ipAddress) Then ipAddress = request.ServerVariables("REMOTE_ADDR") End If ' Get client ip address using UserHostAddress If String.IsNullOrEmpty(ipAddress) Then Dim clientIPA = GetNetworkAddress(request.UserHostAddress) If clientIPA IsNot Nothing Then ipAddress = clientIPA.ToString End If End If End If ' Get local machine ip address If String.IsNullOrEmpty(< |