Comparing a datetimepicker with a string - vb.net

i'm pretty new into coding and visual basic. Today I was assigned to complete a program that i'm having some trouble with. I need to develop an app that allows the user to enter the appointment and the time it needs to be competed, however i need to implement an error check to make sure no two times are the same, this is where i'm running into problems. I'm unsure how i can compare a datetimepicker.value to the listbox text. I'm getting the Conversion from string "" to type Date is not valid error. Any help is much appreciated!
Public Class Form1
Function TimeTaken() As Boolean
Dim app As String = TextBox1.Text
Dim timeofapp As String = DateTimePicker1.Value.ToShortTimeString
If CDate(ListBox2.Text) = CDate(DateTimePicker1.Value) Then
MsgBox("Two appointments are scheduled within the same time frame.", MsgBoxStyle.Exclamation)
TimeTaken = True
Else
TimeTaken = False
ListBox1.Items.Add(app)
ListBox2.Items.Add(timeofapp)
TextBox1.Text = ""
End If
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TimeTaken()
End Sub
End Class

"I'm unsure how i can compare a datetimepicker.value to the listbox text"
You need to iterate over all the values stored in the ListBox.Items() property:
Function TimeTaken() As Boolean
Dim AlreadyTaken As Boolean = False ' assume not taken until proven otherwise below
Dim app As String = TextBox1.Text
Dim timeofapp As String = DateTimePicker1.Value.ToShortTimeString
For Each time As String In ListBox2.Items
If time = timeofapp Then
MsgBox("Two appointments are scheduled within the same time frame.", MsgBoxStyle.Exclamation)
AlreadyTaken = True
Exit For
End If
Next
If Not AlreadyTaken Then
ListBox1.Items.Add(app)
ListBox2.Items.Add(timeofapp)
TextBox1.Text = ""
End If
Return AlreadyTaken
End Function

Related

VB.NET How to receive two values from serial waiting for the second

So I have the code below that is connected to a pager, the problem I have is sometimes a 'page message' will be split across two actual "pages" but if its split it will always contain (part 1 of 2) or (part 2 of 2), the problem I have is that my sub receives the page data and then calls the sub Parse_Page which is fine for single paged massages.
Ive tried to test with an if statement say if PageData.contains ("(Part 1 of 2)") and that's all good and well but I need store that string somewhere and somehow wait for the part message to arrive before putting part 1 and part 2 together and calling the "Parse_page" sub. I've tried various if's and arrays but I;m getting confused in what has to happen. Any ideas on how to do it?
Public Sub serial_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles serial.DataReceived
Dim PageData As String = serial.ReadLine
Parse_Page(Nothing, Nothing)
End Sub
Simply use a global var.
Dim PageData1 As String = String.Empty
Dim PageData2 As String = String.Empty
Public Sub serial_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles serial.DataReceived
If String.IsNullOrEmpty(PageData1) = True Then
PageData1 = serial.Readline
ElseIf String.IsNullOrEmpty(PageData2) = True Then
PageData2 = serial.Readline
PageData = PageData1 & PageData2
PageData1 = String.Empty
PageData2 = String.Empty
Parse_Page(Nothing, Nothing)
End If
End Sub

restarting filename iteration

I wanted to restart the iteration when the system clock hits 00:00 or 12:00 MN. I got the iteration code from the answer of this (below) link, and it works perfectly.
Public Sub GetLastNumber(ByVal filePath As String)
Dim lastFileNo As Integer = 1
Dim files() As String = Directory.GetFiles(filePath, "*.txt")
For Each file As String In files
file = Path.GetFileNameWithoutExtension(file)
Dim numbers As MatchCollection = Regex.Matches(file, "(?<num>[\d]+)")
For Each number In numbers
number = CInt(number.ToString())
If number > 0 And number < 1000 And number > lastFileNo Then lastFileNo = number
Next
lastnumber.Text = number
Next
End Sub
I stumbled something that uses a Timer like this one below, but it's giving me an error saying conversion fail "AM" as String to a Date type.
Public Sub DoStuff(ByVal obj As Object)
MessageBox.Show("It's already time", "TIME!", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Public Sub testT()
Dim tcb As TimerCallback = AddressOf DoStuff
Dim t As Timer
Dim execTime As TimeSpan
Dim dtNow As DateTime = DateTime.Now
Dim hc As Integer = 12
Dim mc As Integer = 0
If TimeOfDay.ToString("tt").Contains("AM") And hc = 12 Then
hc = 0
ElseIf TimeOfDay.ToString("tt").Contains("PM") Then
hc = 12 + (12 - hc)
If hc = 24 Then
hc = 0
End If
End If
Dim dtCandidate As DateTime = New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, hc, mc, 0)
If dtCandidate < dtNow Then
dtCandidate.AddDays(1)
End If
execTime = dtNow.Subtract(dtCandidate)
resultBox.Text = execTime.ToString
t = New Timer(tcb, Nothing, execTime, TimeSpan.Zero)
End Sub
Public Sub realTime_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles realTime.Tick
TimeNow.Text = TimeOfDay.ToString("HH:mm:ss")
testT()
End Sub
Conversion failure was remedied by using TimeOfDay.ToString("tt").Contains("AM/PM"). Un-representable DateTime error was remedied by correcting the ElseIf statements. Since there's no more error, I tried to put the testT function inside a Timer firing at 1000 ms. After system clock hit midnight(00:00), the message box of the DoStuff function showed every second after midnight. How can this be stopped but can still show up the next time the clock hits midnight?
Can somebody help me out?
The code you linked to for the timer is very bad because it is trying to use strings in the manipulation of DateTimes - they are very different things.
I created a new Windows Forms application with only a Label named "TimeNow":
Public Class Form1
Friend WithEvents realTime As Windows.Forms.Timer
Private lastAlarmTime As DateTime
Private alarmTimes As List(Of DateTime)
Private displayTime As String
Public Sub DoStuff()
MessageBox.Show("It's already time", "TIME!", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Public Sub CheckForAnAlarmTime()
Dim dtNow As DateTime = DateTime.Now()
For Each tt In alarmTimes
' the timer interrupt handler is not necessarily called at exact times. Allow for that.
If tt > lastAlarmTime AndAlso tt < dtNow Then
lastAlarmTime = dtNow
DoStuff()
SetAlarmTimes()
Exit For
End If
Next
End Sub
Public Sub realTime_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles realTime.Tick
Dim candidateDisplayTime As String = DateTime.Now.ToString("HH:mm:ss")
' only update the UI if necessary
If candidateDisplayTime <> displayTime Then
displayTime = candidateDisplayTime
TimeNow.Text = displayTime
End If
CheckForAnAlarmTime()
End Sub
Private Sub SetAlarmTimes()
Dim dtNow As DateTime = DateTime.Now()
alarmTimes = New List(Of DateTime)
alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 12, 0, 0))
' Recommendation: do not use exactly midnight without extensive testing, i.e. test over day rollover, month rollover, and year rollover.
' With less testing, use a few milliseconds less than midnight.
alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 0, 0, 0).AddMilliseconds(-50))
End Sub
Private Sub SetUpAlarmsTimer()
SetAlarmTimes()
lastAlarmTime = DateTime.Now()
realTime_Tick(Me, EventArgs.Empty)
realTime = New Windows.Forms.Timer()
realTime.Interval = 200 ' 200ms will update it more accurately w.r.t. visual appearance
AddHandler realTime.Tick, AddressOf realTime_Tick
realTime.Start()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
SetUpAlarmsTimer()
End Sub
End Class
Change the alarmTimes to whatever you need to check that the alarm is raised only once per alarmTimes item.
I am not willing to wait until midnight to check if alarmTimes.Add(New DateTime(dtNow.Year, dtNow.Month, dtNow.Day, 0, 0, 0) without the .AddMilliseconds(-50) will work as required, or until the end of the month or year to be absolutely sure. And please don't forget about testing around the end of February when it is a leap year.
The reason for checking against the lastAlarmTime is that it is not certain when a timer event will be raised: for a timer set to tick at 1000ms, you might get two events inside one real second, or none inside one real second. Approximately.
EDIT: You might also want to work in UTC to avoid hassle with daylight savings time changes.

Variables to list box?

taking a VB class this term and I've been stumped on a problem I'm trying to figure out. We were asked to create a price calculator for movie titles at a movie rental place. Extra credit was storing them in a list and being able to print the list. I've gotten that far and now I want to go a step further and actually add titles to that list with an attached price. I figured the easiest way to do this would probably be with arrays but I don't have much experience working with arrays.
I was thinking something along the lines of storing each title(as its added) as well as the price in a variable to give a "Movie Title - $2.93" format in every line of the list box. For the sake of this problem I'm going to just post my full source code and that might make it easier to see what I'm trying to accomplish. ANY help would be MUCH appreciated. Thanks Stack overflow community!
A screenshot of my project can be viewed here: http://puu.sh/54SgI.jpg
Public Class Form1
'globablly declared because I might use them outside of btnAdd_Click event
Const decDiscount As Double = 0.9 '1-.10 discount = .9
Const decDVD As Decimal = 2D
Const decBlueray As Decimal = 2.5D
Const decDVDNew As Decimal = 3.25D
Const decBluerayNew As Decimal = 3.5D
Dim intCount As Integer
Dim decCost, decTotal As Decimal
Dim decDayTotal As Decimal
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AcceptButton = btnAdd
End Sub
Private Sub chkDiscount_Click(sender As Object, e As EventArgs) Handles chkDiscount.Click
If chkDiscount.CheckState = 1 Then
chkDiscount.Enabled = False
End If
End Sub
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
'Display error when no title entered
If txtAdd.Text = "" Then
MessageBox.Show("Please enter a movie title and select the appropriate item details.", "Complete details", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
listMovies.Items.Add(txtAdd.Text)
listMovies.SelectedIndex = listMovies.SelectedIndex + 1
End If
'update list
'clear txtbox
txtAdd.Text = ""
'Decision Statements to calculate correct price
If radDVD.Checked = True Then
decCost = CDec(decDVD.ToString("c"))
If chkNew.Checked = True Then
decCost = CDec(decDVDNew.ToString("c"))
End If
ElseIf radBlueray.Checked = True Then
decCost = CDec(decBlueray.ToString("c"))
If chkNew.Checked = True Then
decCost = CDec(decBlueray.ToString("c"))
End If
End If
If chkDiscount.Checked = True Then
decCost = CDec((decCost * decDiscount).ToString("c"))
End If
'display cost
txtCost.Text = CStr(CDec(decCost))
'calc total
decTotal = CDec(decTotal + decCost)
'display total
txtTotal.Text = CStr(CDec(decTotal))
'clear chkNew every item added to list
chkNew.CheckState = 0
End Sub
'Public so summary message box can access variable
Public Sub btnFinish_Click(sender As Object, e As EventArgs) Handles btnFinish.Click
'Add +1 to counter & update txtCounter
intCount = CInt(Val(intCount) + 1)
'add to day total
decDayTotal = CDec(Val(decDayTotal) + decTotal)
'Set Everything back to empty/enabled
chkDiscount.Enabled = True
chkDiscount.CheckState = 0
chkNew.CheckState = 0
txtAdd.Text = ""
txtCost.Text = ""
txtTotal.Text = ""
decTotal = 0
decCost = 0
'Instead of clearing radios each time, a more desirable result would be to have DVD always set back to the default checked radio
radDVD.Checked = True
radBlueray.Checked = False
listMovies.Items.Clear()
End Sub
Private Sub btnSummary_Click(sender As Object, e As EventArgs) Handles btnSummary.Click
If decTotal > 0 Then
MessageBox.Show("Please finish your current order before viewing a daily summary.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
MessageBox.Show(("Your total cutomer count is: " & intCount) + Environment.NewLine + ("Your total sales today is: $" & decDayTotal), "Daily Summary", MessageBoxButtons.OK)
End If
End Sub
Private Sub btnRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRemove.Click
listMovies.Items.Remove(listMovies.SelectedItem)
End Sub
I wont go very far here because you need to do the work. But, I would start with a class:
Public Class Movie
Public Title As String = ""
Public Cost As Decimal
' prevents you from adding a movie without critical info
Public Sub New(ByVal t As String, ByVal c As Decimal)
Title = t
Cost = c
End Sub
End Class
This would hold the info on one movie title rental, and keep it together (and can be added to in order to print exactly as you showed) . The plan (to the extent I understand what you are after) would be to create one of these for each movie rented and add it to a List(Of Movie) this is more appropriate than a Dictionary in this case.
To create a movie:
Dim m As New Movie(theTitle, theCost)
Things I would do:
You did a good job of declaring numerics as numbers. Fix the code that converts it to string and back to numeric. (edit your post)
You can use the Movie Class to populate the "Shopping Cart" listbox alone; at which point, listMovies.Items would BE the extra credit List. But it wouldnt hurt to use/learn about List (Of T). (BTW, does 'print' mean to paper, on a printer?)
What are you doing with chkDiscount? If they check it, you disable it (and never enable). Did you mean to disable the New Releases check? In THAT case, arent they really a pair of radios too?
Either way, CheckChanged is a better event for evaluating and there is no reason to manually set the check state for the user that happens by itself.
Check out List(of T) and HTH
A good thing to think about when doing assignments like this (particularly when learning your first language) is to think of the algorithm (the step you need to get to your goal).
1st, determine all the steps you need to get to your goal.
2nd, and I think this is the more import point for your question, figure out what order the steps need to be in (or better yet, what order they are most efficient in).
In your case I think that you are kind of ice skating up hill by adding the name of the movie to the list first, and then trying to add the price to the line later. Unless that kind of functionality was requested as part of the assignment I would require the user to enter both the name AND the price before accepting either (just like you do with the name currently). Like thus:
If txtAdd.Text <> "" AND txtCost.Text <> "" Then 'requiring both fields to not be null
''add moive code
Else
''MessageBox.Show("Yadda Yadda Yadda")
End If
I agree with Plutonix that creating a class, while overkill in your case, is a good idea, as it will give you practice for when it WILL be appropriate. Once you have that a class of Movie, you can then create lists of Movie(s) like this:
Dim MovieList as new List(of Movie)
So then, each time you press the btnAdd button, you can pass the values to a movie AND add it to the list.
Dim m As Movie
Dim MovieList as new List(of Movie)
Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
'Display error when no title entered
If txtAdd.Text <> "" And txtCost.Text <> "" Then
myMovie = New Movie(txtAdd.Text, txtCost.Text)
myMovieList.Add(myMovie)
listMovies.Items.Clear()
For Each X As Movie In myMovieList
listMovies.Items.Add(X.DisplayMovie)
Next
Else
MessageBox.Show("Please enter a movie title and select the appropriate item details.", "Complete details", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
'Other Code
End Sub
Note the line ListMovies.Items.Add(X.DisplayMovie) I added a function to the class Movie (seen below) so that it will do the formatting as you suggested.
Public Function DisplayMovie()
Return Title & " - $" & Cost
End Function
This will get you much of the way. Try to extrapolate what Plutonix and myself have explained to further refine your code. For instance, try encapsulating your adjusted price calculation in its own function so you can call it from anywhere.

validating alphanumeric input in textbox [VB2010]

im newbie here, im using vb2010, i just need some help guys.
here's my problem.
i want to validate user's input on my textbox, when user input like this "1a1:b2b:3c3", my project should accept it. but when user input like this "1a1b2b3c3", it will show a msgbox that the format must be "XXX:XXX:XXX".thanks for help in advance.
I done up a very quick example for you, more than enough to get you on the right track. I could have done it a different way, but I am sure this will get you going. I used MaxLength to determine that the user input at least 9 characters and if not let them know. I also made a function that passes the textbox's text into this and will go ahead and format it for you; saves the user time... besides we just need to make sure user primarily enters at least 9 characters anyways if I am correct... Good Luck!
Public Class Form1
Private strValidatedText As String = String.Empty
Private blnValid As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Make sure user can only enter up to 9 values...
With txtInput
.MaxLength = 9
.TextAlign = HorizontalAlignment.Center
End With
End Sub
Private Sub btnValidate_Click(sender As Object, e As EventArgs) Handles btnValidate.Click
Dim strTextBox As String = txtInput.Text
strValidatedText = ValidateText(strTextBox)
Select Case blnValid
Case True
MessageBox.Show("It's valid! " & strValidatedText)
txtInput.Clear()
txtInput.Focus()
Case Else
MessageBox.Show(strValidatedText)
txtInput.Clear()
txtInput.Focus()
End Select
End Sub
Private Function ValidateText(ByVal strText As String)
Dim strNewText As String = String.Empty
If strText.Length = 9 Then
strNewText = (strText.Substring(0, 3) & ":" & strText.Substring(3, 3) & ":" & strText.Substring(6, 3))
blnValid = True
Else
strNewText = "There must be at least 9 characters in the textbox!"
blnValid = False
End If
Return strNewText
End Function
End Class
Also at that point in the "Select Case blnValid", you can do what ever you would like with that string because it's global...
MrCodeXeR
I would suggest you to use MaskedTextBox class, it will help you to take a formatted input from user. Have a look at this example.
I tried it with following code and it works fine in VB 2010. Just use this code before your variable declaration:
If TextBox1.Text = "" Then 'check if the textbox has a value
MsgBox("Please Enter ID Number")
Return 'will return to the app
ElseIf Not IsNumeric(TextBox1.Text) Then 'check if the entered value is a number
MsgBox("ID Must Be A Number")
Return

In vb.net, how do I force validating controls within a (winform) datarepeater after the data is populated?

I have a form with a datarepeater that contains various controls (i.e. datetimepickers, text boxes, combo box) that are populated via a binding source. I also have other controls on the form that are not part of the data repeater.
I would like to force validating all controls after the data is populated. I have successfully forced validating the non-datarepeater controls using Me.ValidateChildren() at the end of my load event. However, it does not fire the validating events for the controls within the data repeater.
I have unsuccessfully tried many different attempts to set and move focus within the datarepeater controls trying to get the validating events kicked off. I am not sure where would be the best place (e.g. in drawItem? in ItemCloned?) to place the code and what it should be exactly. Here was my latest attempt:
Private Sub DataRepeater1_DrawItem(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs) _
Handles DataRepeater1.DrawItem
For i = 0 To e.DataRepeaterItem.Controls.Count - 1
e.DataRepeaterItem.Controls.Item(i).Focus()
e.DataRepeaterItem.Controls.Item(0).Focus()
Next
Note: I successfully handled the validating events in the data repeater caused by user input errors. However, I have the unusual situation that the data coming into my form is already bad for some of the controls. The purpose of the form is to validate the data coming in to it and from user-input.
Thanks in advance for any help. I am newbie with vb.net.
Have you tried calling
DataRepeater1.ValidateChildren()
after calling form's Me.ValidateChildren()
MSDN link
EDIT:
Can you try this
Private Shared Function ValidateAllChildern(cc As ContainerControl) As Boolean
Return cc.ValidateChildren() And cc.Controls.OfType(Of ContainerControl)().[Select](Function(c) ValidateAllChildern(c)).Aggregate(True, Function(x, y) x And y)
End Function
and call
ValidateAllChildren(Me)
Here is what I ended up using and it worked great. Basically, you can call the same validation functions in cellformatting and cellvalidating. Cell formatting handles the validation on initial load. Cell validating handles validation on user changes. Also, if you want a global change on user entry (e.g. change to upper case), use EditControlShowing.
A nice feature too is that it shows the little error icon in the cell the error occurred on. Here are the details, fyi.
'handles dgv validation on initial load
Private Sub dgvExample_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
Handles dgvExample.CellFormatting
Dim results As String = ""
If e.RowIndex <> -1 Then
Select Case e.ColumnIndex
Case 1, 2 'starting and ending service dates
results = ValidateDate(e.Value)
If results = "" Then
results = ValidateDateRange(e.RowIndex)
End If
Case 11 'billed amount
results = ValidateBilledAmount(e.RowIndex)
End Select
dgvExample.Rows(e.RowIndex).Cells(e.ColumnIndex).ErrorText = results
End If
End Sub
'handles dgv validation from user changes
Private Sub dgvExample_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) _
Handles dgvExample.CellValidating
Dim results As String = String.Empty
dgvExample.CurrentCell.ErrorText = String.Empty
Select Case dgvExample.Columns(e.ColumnIndex).HeaderText
Case "Start Date", "End Date"
results = ValidateDate(e.FormattedValue)
If results = "" Then
results = ValidateDateRange(e.RowIndex)
End If
Case "Billed Amt"
dgvExample(e.ColumnIndex, e.RowIndex).Value = FormatNumber(CType(e.FormattedValue, Double), 2, TriState.False, TriState.False, TriState.False).ToString
results = ValidateBilledAmount(e.RowIndex)
End Select
dgvExample.CurrentCell.ErrorText = results
End Sub
'handles dgv dataentry events
Private Sub dgvExample_EditingControlShowing(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _
Handles dgvExample.EditingControlShowing
'Change Case to upper case for all textboxes
Dim editingControl As TextBox = TryCast(e.Control, TextBox)
If editingControl IsNot Nothing Then
editingControl.CharacterCasing = CharacterCasing.Upper
End If
End Sub
'FUNCTIONS called in above
'check dates not old or in future
Private Function ValidateDate(ByVal dte As String) As String
Dim errorMessage As String = ""
If CType(dte, Date) > Now Then
errorMessage = "DATE cannot be in the future"
Return errorMessage
End If
If CType(dte, Date) <= Now.Date.AddYears(-1) Then
errorMessage = "WARNING: DATE cannot be older than 1 year"
Return errorMessage
End If
Return errorMessage
End Function
'Checks that start date is less than end date
Private Function ValidateDateRange(ByVal rowIndex As Integer) As String
Dim errorMessage As String = ""
If CType(dgvExample.Rows(rowIndex).Cells(1).Value, Date) > _
CType(dgvExample.Rows(rowIndex).Cells(2).Value, Date) Then
errorMessage = "START DATE cannot be after END DATE"
End If
Return errorMessage
End Function
'validates billed amount is currency and in range
Private Function ValidateBilledAmount(ByVal rowIndex As Integer) As String
Dim errorMessage As String = ""
Dim billedAmt = dgvExample.Rows(rowIndex).Cells(11).Value
If Not String.IsNullOrEmpty(billedAmt) Then
If IsNumeric(billedAmt) Then
If CType(billedAmt, Decimal) > 0 Then
If billedAmt > 100000.0 Then
errorMessage = "BILLED AMOUNT must not exceed $100,000"
End If
Else
errorMessage = "BILLED AMOUNT must be greater than $0"
End If
Else
errorMessage = "BILLED AMOUNT must be numeric"
End If
End If
If errorMessage = "" Then
CalculateNewTotal()
End If
Return errorMessage
End Function
I just tested this and in order to get the ValidateChildren to work, you need to programmatically set the event handler using AddHandler.
Private Sub DataRepeater1_DrawItem(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs) _ Handles DataRepeater1.DrawItem
AddHandler e.DataRepeaterItem.Controls.Item("ctlDateTimePicker").Validated, AddressOf dtpStartingServiceDate_Validating ' Validating DatePicker
AddHandler e.DataRepeaterItem.Controls.Item("ctlComboBox").Validated, AddressOf cboUnitType_Validating
End Sub
Once the Validated event handler is initialized, you can then call 'Me.ValidateChildren()' to cause the validation to run. I don't know if it's good or bad for your situation but the validation event will execute whenever the control's value is changed.
Let me know if that works.