Show calendar in Ultragrid Column Filter - vb.net

I have an UltraGrid in which I have many columns of which 2 columns are DateTime style. Now when I use the filter of that columns it shows all the DateTime values as a text in a dropdown. But I need that as a calendar in order to make the filter easy. It is enough to show just a calendar when clicking the filter.
I have tried some code but it doesn't work.
//Code:
Private Sub grdResult_BeforeRowFilterDropDown(ByVal sender As Object, ByVal e As Infragistics.Win.UltraWinGrid.BeforeRowFilterDropDownEventArgs) Handles grdResult.BeforeRowFilterDropDown
e.Cancel = True
UltraCalendarCombo1.Visible = True
UltraCalendarCombo1.Location = New Point(grdResult.Rows.FilterRow.Cells(e.Column).GetUIElement().Rect.Location.X, grdResult.Rows.FilterRow.Cells(e.Column).GetUIElement().Rect.Location.Y - 2)
UltraCalendarCombo1.Size = New System.Drawing.Size(grdResult.Rows.FilterRow.Cells(e.Column).GetUIElement().Rect.Size.Width, grdResult.Rows.FilterRow.Cells(e.Column).GetUIElement().Rect.Size.Height)
' UltraCalendarCombo1.DroppedDown = True
End Sub
The above event will fire when the filter dropdown is clicked.
private sub applyCustomeViewSettings(byval gridFormat as GridFormat)
....
...
For Each ColumnFormat In gridFormat.ColumnFormats
For Each column In Me.grdResult.DisplayLayout.Bands(0).Columns
If column.Key.ToUpper = ColumnFormat.ColumnKey.ToUpper Then
If column.Key.ToUpper = "PCSSTDT" Then
column.Header.Caption = IIf(ColumnFormat.Caption = "", ColumnFormat.ColumnKey, ColumnFormat.Caption)
column.Hidden = ColumnFormat.Hidden
'column.AllowRowFiltering = IIf(ColumnFormat.AllowRowFiltering = False, ColumnFormat.AllowRowFiltering, DefaultableBoolean.True) 'CType(ColumnFormat.AllowRowFiltering, DefaultableBoolean)
column.Width = ColumnFormat.Width
column.Header.VisiblePosition = ColumnFormat.VisiblePosition
column.Format = ColumnFormat.Format
column.SortIndicator = ColumnFormat.SortIndicator
' column.Style = ColumnStyle.Date
'column.EditorComponent = UltraCalendarCombo1
column.FilterOperandStyle = FilterOperandStyle.Default
Else
column.Header.Caption = IIf(ColumnFormat.Caption = "", ColumnFormat.ColumnKey, ColumnFormat.Caption)
column.Hidden = ColumnFormat.Hidden
column.AllowRowFiltering = IIf(ColumnFormat.AllowRowFiltering = False, ColumnFormat.AllowRowFiltering, DefaultableBoolean.True) 'CType(ColumnFormat.AllowRowFiltering, DefaultableBoolean)
column.Width = ColumnFormat.Width
column.Header.VisiblePosition = ColumnFormat.VisiblePosition
column.Format = ColumnFormat.Format
column.SortIndicator = ColumnFormat.SortIndicator
column.Style = ColumnFormat.Style
End If
End If
Next
....
...
End Sub
The above method makes the grid changes(apply settings) to show the filter as calendar.
But this doesn't work and showing me the same normal grid.
How can I achieve this?

I have managed to show a MonthCalendar when you press the icon to filter a DateTime column in an UltraWinGrid.
When the MonthCalendar is dispayed you could select a specific date using the familiar interface provided by this standard WinForm control. After selecting the date you could use the value to apply programmatically a filter condition to the UltraWinGrid column.
To reach this result you first need to add a reference to the Infragistics4.Win.SupportsDialog.v11.2 assembly where you can find the UltraGridFilterUIProvider class
Now, in your form where you need the filtering to appear, add this code: (it is just an example because I haven't your datasource and thus I have a prebuilt one with just one datetime column)
Imports Infragistics.Win.UltraWinGrid
Imports Infragistics.Win.SupportDialogs.FilterUIProvider
Public Class Form1
' This is the key object that let us customize '
' the Filter for the UltraWinGrid'
Dim _filterUIProvider as UltraGridFilterUIProvider
' In the InitializeLayout event we substitute the normal
' filter handler with the custom filter'
Private Sub UltraGrid1_InitializeLayout(sender As Object, e As Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs) Handles UltraGrid1.InitializeLayout
e.Layout.Override.AllowRowFiltering = Infragistics.Win.DefaultableBoolean.True
_filterUIProvider = New UltraGridFilterUIProvider()
' Comment out the following line to test the default
' **Excel Filter Style Interface** '
AddHandler _filterUIProvider.BeforeMenuPopulate, AddressOf _filterUIProvider_BeforeMenuPopulate
e.Layout.Override.FilterUIProvider = _filterUIProvider
End Sub
' Before the UltraGridFilterUIProvider shows its standard form interface
' we start a custom form used to apply our filtering logic '
' and block the display of the UltraGridFilterUIProvider interface '
Private Sub _filterUIProvider_BeforeMenuPopulate(sender As Object, e As Infragistics.Win.SupportDialogs.FilterUIProvider.BeforeMenuPopulateEventArgs)
' A custom form with the MonthCalendar and 3 buttons '
' to handle the filter logic '
Using fDate = new FormDate()
' Open our custom form with the monthcalendar
if (DialogResult.OK = fDate.ShowDialog())
' We need a nullable date to allow the removing of the filter'
Dim dtFilter As DateTime? = fDate.SelectedDate
if (dtFilter.HasValue)
' Apply programmatically a filtercondition to the column
' In this case I have only one column. so I use the index 0
' in your case this should change to reflect your column index
Dim fc = new FilterCondition(FilterComparisionOperator.Equals, dtFilter.Value)
ultraGrid1.DisplayLayout.Bands(0).ColumnFilters(0).FilterConditions.Add(fc)
Else
ultraGrid1.DisplayLayout.Bands(0).ColumnFilters.ClearAllFilters()
End If
End If
End Using
e.Handled = true ' Stop the standard interface'
End Sub
End Class
Now we need only a simple form called FormDate that contains a MonthCalendar and three buttons (Set, Clear, Cancel) that return (Set) a Date to set the filter, (Clear) a null value to remove previous filter and a cancel button to abort the processing
Here the code for the form, the design is trivial
Public Class FormDate
Public Property SelectedDate As DateTime?
Private Sub FormDate_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.SelectedDate = Nothing
End Sub
Private Sub cmdSet_Click(sender As Object, e As EventArgs) Handles cmdSet.Click
'This button has DialogResult=OK'
Me.SelectedDate = monthCalendar1.SelectionStart
End Sub
Private Sub cmdClear_Click(sender As Object, e As EventArgs) Handles cmdClear.Click
'This button has DialogResult=OK'
Me.SelectedDate = Nothing
End Sub
End Class
This could resolve your problem, however, I have discoverd what seems to be a bug in UltraGridFilterUIProvider. When I call the e.Handled=True my expected result is the filter to not show anything but, instead a small window still appears and I have to press Escape to hide it. I have not found any way to automatically hide it.
It seems to be a problem to signal to the Infragistics team.
I suggest you also to test the Excel Style Filter Interface provided automatically by the UltraGridFilterUIProvider. This interface has a lot of options and is much more preferable to the standard UI filter. To test this interface you should only comment out the AddHandler line above
EDIT Following the comment from #Alhalama I have tried to use the BeforeRowFilterDropDown event and the result are better (well it is perfect now). So I have commented out the line with the AddHandler, removed the code for the BeforeMenuPopulate and added the code for the BeforeRowFilterDropDown
Private Sub UltraGrid1_BeforeRowFilterDropDown(sender As Object, e As BeforeRowFilterDropDownEventArgs) Handles UltraGrid1.BeforeRowFilterDropDown
If e.Column.Key = "DateRequest" Then
Using fDate = New FormDate()
If DialogResult.OK = fDate.ShowDialog() Then
Dim dtFilter As DateTime? = fDate.SelectedDate
If (dtFilter.HasValue) Then
Dim fc As FilterCondition = New FilterCondition(FilterComparisionOperator.Equals, dtFilter.Value)
UltraGrid1.DisplayLayout.Bands(0).ColumnFilters(0).FilterConditions.Add(fc)
Else
UltraGrid1.DisplayLayout.Bands(0).ColumnFilters.ClearAllFilters()
End If
End If
End Using
e.Cancel = True
End If
End Sub
Now, when I try to open the filter for the column named DateRequest I open immediately the FormDate and at the end I set the Cancel property of the BeforeRowFilterDropDownEventArgs to true to avoid further processing of the filter dialog. This seems to be perfect...... Great credit for this to Mr. Alhalama. If you wish I think you should post your own answer because your suggestion really makes the difference.

Related

How would you structure data with different datatypes in VB.NET

Right now I have many locations with this structure. At the moment I have: name as string and x,y,z positions as single. So it's a mix of data types and I might want to add both more data in the future and also other data types. I must be able to easily extract any part of this data.
Example of how I'll work with this data is: When I choose South Wales from a combobox then I want to get its properties, x,y,z populated in a textbox. So they need to be "linked". If I choose London then it'll have its x,y,z properties etc.
My initial idea is just to dim every single data such as in the first example below. This should be the easiest way with 100% control of what's what, and I could easily extract any single data but at the same time might get tedious I assume, or am I wrong? Is it a good way to approach this?
Dim SW_FP As String = "South Wales"
Dim SW_FP_X As Single = "489,1154"
Dim SW_FP_Y As Single = "-8836,795"
Dim SW_FP_Z As Single = "109,6124"
The next example below is something i just googled up. Is this a good method?
Dim dt As DataTable = New DataTable
dt.Columns.Add("South Wales", GetType(String))
dt.Columns.Add("489,1154", GetType(Single))
dt.Columns.Add("-8836,795", GetType(Single))
dt.Columns.Add("109,6124", GetType(Single))
OR should I use something else? Arrays, Objects with properties... and this is where my ideas end. Are there other methods? XML?
I want to do it in a smart way from start instead of risking to rewrite/recreate everything in the future. So my main question is: Which method would you suggest to be the smartest to choose? and also if you could provide a super tiny code example.
You mentioned that when you choose an item you want to get it's properties. This shows that you are looking for objects. If not using a database one example could be to make Location objects and have a List of these to be added or removed from. Then you have a lot of different ways to get the data back from the List. For example:
Class:
Public Class Location
Public Property Name As String
Public Property X As Single
Public Property Y As Single
Public Property Z As Single
End Class
List:
Dim locations As New List(Of Location)
Dim location As New Location With {
.Name = "South Wales",
.X = 1.1,
.Y = 1.2,
.Z = 1.3
}
locations.Add(location)
LINQ to get result:
Dim result = locations.SingleOrDefault(Function(i) i.Name = "South Wales")
This is just an example for use within your program, hope it helps.
Disclaimer: Untested code. It's more to guide you than copy-paste into your project.
First, create a Class that will represent the structured data:
Public Class Location
Public Property Name As String
Public Property PositionX As Single
Public Property PositionY As Single
Public Property PositionZ As Single
Public Sub New()
Me.New (String.Empty, 0, 0, 0)
End Sub
Public Sub New(name As String, x As Single, y As Single, z As Single)
Me.Name = name
Me.PositionX = x
Me.PositionY = y
Me.PositionZ = z
End Sub
Now, you can create a List(Of Location) and use that List to bind to a ComboBox, like this:
Dim list As New List(Of Location) = someOtherClass.ReadLocations ' Returns a List(Of Location) from your database, or file, or whatever.
cboLocations.DataSource = list
cboLocations.DisplayMember = "Name" ' The name of the Location class' Property to display.
cboLocations.ValueMember = "Name" ' Use the same Name Property since you have no ID.
You can also forego the list variable declaration like the following, but I wanted to show the declaration of list above:
cboLocations.DataSource = someOtherClass.ReadLocations
Function someOtherClass.ReadLocations() may populate the List(Of Locations) in a way similar to this. Note I'm not including data access code; this is just an example to show how to add Location objects to the List(Of Location):
Dim list As List(Of Location)
' Some loop construct
For each foo in Bar
Dim item As New Location(foo.Name, foo.X, foo.Y, foo.Z)
list.Add(item)
' End loop
Return list
The "magic" happens when you select an option from the ComboBox. I forget the ComboBox event offhand, so that's homework for you :-) You take the selected Object of the ComboBox and cast it back to the native type, in this case Location:
Dim item As Location = DirectCast(cboLocations.SelectedItem, Location)
txtName.Text = item.Name
txtPosX.Text = item.PositionX.ToString
txtPosY.Text = item.PositionY.ToString
txtPosZ.Text = item.PositionZ.ToString
Here is one way, using a DataTable as you mentioned. This is a stand alone example project just to show code used.
This example loads data from file is found and saves data on exit.
Form1 Image
' Stand alone example
' needs DataGridView1, Label1 and
' ComboBox1 on the Designer
' copy/replace this code with default
Option Strict On
Option Explicit On
Public Class Form1
Dim dt As New DataTable("Freddy")
Dim bs As New BindingSource
'edit path/filename to use as test data path
Dim filepath As String = "C:\Users\lesha\Desktop\TestData.xml"
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
dt.WriteXml(filepath)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
With dt
dt.Columns.Add("Country", GetType(String))
dt.Columns.Add("x", GetType(String))
dt.Columns.Add("y", GetType(String))
dt.Columns.Add("z", GetType(String))
' add extra column to hold concatenated
' location (could be a hidden column)
dt.Columns.Add("CombLoc", GetType(String), "'x = ' + x + ' y = ' + y + ' z = ' + z")
If IO.File.Exists(filepath) Then
' saved file found so load it
dt.ReadXml(filepath)
Else
' no saved file so make one test row
.Rows.Add("South Wales", 489.1154, -8836.795, 109.6124)
End If
End With
bs.DataSource = dt
DataGridView1.DataSource = bs
' set any properties for DataGridView1
With DataGridView1
' to hide Combined Location column
.Columns("CombLoc").Visible = False
' dontwant row headers
.RowHeadersVisible = False
End With
set up ComboBox
With ComboBox1
.DataSource = bs
' displayed item
.DisplayMember = "Country"
' returned item
.ValueMember = "CombLoc"
If .Items.Count > 0 Then .SelectedIndex = 0
End With
' default Label text
Label1.Text = "No items found"
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
no items in list so exit sub
If ComboBox1.SelectedIndex < 0 Then Exit Sub
send returneditem to Label
Label1.Text = ComboBox1.SelectedValue.ToString
End Sub
End Class

Pass integer value from one form to another in VB.NET

I'm writing a program that has two forms. One form gets the user to enter multiple values, and then does some calculations. Then it passes that information to another form However I can't figure out how to do it. Here is a relevant part of my code. To head some confusion, I am trying to pass 11 values, also initially, form 2 is not shown, and then when the values are passed from form 1 to form 2, then form 1 goes away and form 2 is the only one that shown
NOTE: This is not all my code, I don't believe all my code is required (I have 1000 lines right now) However this is the code with the information I want to be passed to the other form.
A lot of people are apparently saying that this is a duplicate of another question, however that question, he seems to already know how to pass the variables, but is just having issues with it (and even with looking at his, i cant figure it out)
Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
'declarations
Dim intNormal As Integer
Dim intChildren As Integer
Dim intBonanza As Integer
Dim intDiamond As Integer
Dim intPictureFrame As Integer
Dim intKite As Integer
Dim intCrazyT As Integer
Dim intLetterX As Integer
Dim int2PostageStamp As Integer
Dim intPick7 As Integer
Dim intJackpot As Integer
Validate()
If txtNormal1.Enabled = False Then
intNormal = intNormInput
Else
intNormal = CalcNormalBooks()
End If
If txtChildren1.Enabled = False Then
intChildren = intChildInput
Else
intChildren = calcChildrensBooks()
End If
If txtBonanza1.Enabled = False Then
intBonanza = intBonInput
Else
intBonanza = calcBonanza()
End If
If txtSpecial1.Enabled = False Then
intSpecial = intSpeInput
Else
intSpecial = calcSpecialBooks(intSpecial)
End If
If txtDiamond1.Enabled = False Then
intDiamond = intDiaInput
Else
intDiamond = calcDiamond(intSpecial)
End If
If txtPictureFrame1.Enabled = False Then
intPictureFrame = intPicInput
Else
intPictureFrame = calcPictureFrame(intSpecial)
End If
If txtKite1.Enabled = False Then
intKite = intKiteInput
Else
intKite = calcKite(intSpecial)
End If
If txtCrazyT1.Enabled = False Then
intCrazyT = intCrazyInput
Else
intCrazyT = calcCrazyT(intSpecial)
End If
If txtLetterX1.Enabled = False Then
intLetterX = intLettInput
Else
intLetterX = calcLetterX(intSpecial)
End If
If txt2PostageStamp1.Enabled = False Then
int2PostageStamp = intPostInput
Else
int2PostageStamp = CalcPostageStamp(intSpecial)
End If
If txtPick71.Enabled = False Then
intPick7 = intPickInput
Else
intPick7 = calcPick7(intSpecial)
End If
If txtJackpot1.Enabled = False Then
intJackpot = intJackInput
Else
intJackpot = calcJackpot()
End If
End Sub
Since I had almost the same requiremnt lately here is my solution:
Custom Event which fires when your 2nd Form is closing
Public Event HotKeyFormClosed As EventHandler(Of HotKeyFormClosedEventArgs)
Custom EventArgs class where you store your values you want to pass to Main Form
Public Class HotKeyFormClosedEventArgs
Inherits EventArgs
'Your properties here
Public Sub New(...) 'your params here
MyBase.New()
'set your properties here
End Sub
End Class
On 2nd Form handle FormClosed event and pass your values to EventArgs
Private Sub HotKey_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs)
RaiseEvent HotKeyFormClosed(Me, New HotKeyFormClosedEventArgs(...)) 'your params here
End Sub
On Main Form handle your custom event (here HotKeyFormClosed) and extract its values
AddHandler frmHotKey.HotKeyFormClosed, AddressOf HotKey_FormClosed;
...
Private Sub HotKey_FormClosed(sender As Object, e As HotKeyFormClosedEventArgs)
'Do stuff with values from e
End If
I have chosen the Event approach since it decouples the two forms from another.
One could easily duplicate the information on both forms, make them public and access it directly thru an object instance.
But I like the observable approach from the events more due to it gives mor flexibility (additonal forms using the same events etc.)
P.S.: I wrote my code in c# and blind entered the VB code here so be gracious.
The values/variables that a method expects to receive (specified in the method's signature) are called Parameters.
The values sent to a method when the method is called are called Arguments.
As long as the arguments used when calling a method match the parameters for that method, those values can be passed.
For example (and I'll try to apply this to your context), if you want to create an instance of a form that takes certain values, you can specify those parameters in the form's New event, like so:
Public Sub New(someInt As Integer)
'do something with someInt here
End Sub
Then when you call this method you'd pass it the arguments, like so:
Dim myInt As Integer = 10
Dim newForm As myForm = New myForm(myInt)
When I say the arguments need to match the parameters, that means the number of values, the order of those values, and the value types must be the same (or in the case of numbers the parameter's type must be the same or larger than the argument's type).
As long as that is true, then it shouldn't really matter how you pass these - you could pass 11 individual arguments, you just have to make sure you are matching the argument to the parameter.
Hope that helps!

How to use checkbox to select my data

i am using vb.net with microsoft sql
i want to retrieve data where the checkbox is selected how could i perform it?
this the code i currently have
Dim chk As New DataGridViewCheckBoxColumn()
DataGridView1.Columns.Add(chk)
chk.HeaderText = "Select"
chk.Name = "lol"
sql.RunQuery("Select ID,JobPosition,requiredQualification,Salary, description,JobExpYear from vacancy where JobPosition IN (Select JobPosition from employer where EID = '" & ID & "')")
If sql.SQLDS.Tables.Count > 0 Then
DataGridView1.DataSource = sql.SQLDS.Tables(0)
End If
i will have checkbox within my data grid, how do i call it?
I'm not sure if this is what you need, question not clear enough for me. But see if this helps:
Dim condition As String = String.Empty
For Each row As DataGridViewRow In DataGridView1.Rows
condition += DirectCast(row.Cells(0), DataGridViewCheckBoxCell).Selected.ToString + ", "
Next
If Not String.IsNullOrEmpty(condition) Then
'Remove last splitter
condition = condition.Substring(0, condition.Length - 2)
End If
Your question: "i am using vb.net with microsoft sql i want to retrieve data where the checkbox is selected how could i perform it?"
There are a few different ways that this can be accomplished. You can either one, create a function that returns if it's checked or not or create a method that does all of your logic for you, it depends on how your going to use it. According to your query your not getting any information from the DataGridView, you are saying you want to retrieve data if it's checked or not. Another question is what is the purpose of running the same query if you have multiple rows, are you going to be running different queries based on the CheckBox for that row if it's checked?
Example 1 -Create a function to see what the value is
''' <summary>
''' Returns if given column is checked or not
''' </summary>
''' <param name="dGrid"></param>
''' <param name="dRow"></param>
''' <param name="intIndex"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Shared Function IsColumnChecked(ByVal dGrid As DataGridView, ByVal dRow As DataGridViewRow, ByVal intIndex As Integer) As Boolean
Dim blnIsChecked As Boolean = False
Try
'What column is the checkboxcolumn and let's make sure its the correct type
If TypeOf (dGrid.Columns(intIndex)) Is DataGridViewCheckBoxColumn Then
If dGrid.RowCount <> 0 Then
If CBool(DirectCast(dRow.Cells(intIndex), DataGridViewCheckBoxCell).Value) Then
blnIsChecked = True
End If
Else
Return blnIsChecked
End If
Else
Return blnIsChecked
End If
Catch ex As Exception
Return blnIsChecked
End Try
Return blnIsChecked
End Function
Example 1 Useage - Check to see if given row is checked or not-
'Example ONLY on a button click...
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
If IsColumnChecked(DataGridView1, DataGridView1.CurrentRow, 0) Then
MessageBox.Show("It's Checked!")
Else
MessageBox.Show("Not Checked!")
End If
End Sub
You can also put this in a method to do what you want with other logic, not sure how you are going to use it. This function is good to determine if you want to continue with other things or not and can be used in other areas of your program as well.
Good Luck!

Issue saving custom DateEdit and TimeEdit fields using a custom AppointmentEdit form

I have a custom EditAppointment form that contains 3 sets of Start and End fields.
The Start and End fields in the Planning section are the default appointment fields that are bound to Start and End in the Scheduler mappings.
The Start and End fields under Published and Actual are read only and are the same type of fields as under Planning (DevExpress.XtraEditors.DateEdit and DevExpress.XtraEditors.TimeEdit), but get and save their values to CustomFields mapped in the Scheduler mappings.
The custom fields are defined as Properties:
Public Class MyAppointmentFormController
Inherits AppointmentFormController
...
Public Property CustomPublishedStartDateTime() As DateTime
Get
Return CDate(EditedAppointmentCopy.CustomFields("PublishedStartDateTime"))
End Get
Set(ByVal value As DateTime)
EditedAppointmentCopy.CustomFields("PublishedStartDateTime") = value
End Set
End Property
Public Property CustomPublishedCompletedDateTime() As DateTime
Get
Return CDate(EditedAppointmentCopy.CustomFields("PublishedCompletedDateTime"))
End Get
Set(ByVal value As DateTime)
EditedAppointmentCopy.CustomFields("PublishedCompletedDateTime") = value
End Set
End Property
...
End Class
I change the Start and End dates under Planning until things line up on the timeline and then I click the Publish which copies data from planning to publish:
' Copies Planned data to Published
Private Sub btnPublishJob_Click(sender As Object, e As EventArgs) Handles btnPublishJob.Click
txtCustomPublishedPackagingLine.Text = AppointmentResourceEdit1.Text
txtCustomPublishedRunRatePerShift.Text = txtCustomPlanningRunRatePerShift.Text
dtPublishedStart.EditValue = dtPlanningStart.EditValue
timePublishedStart.EditValue = New DateTime(timePlanningStart.Time.TimeOfDay.Ticks)
dtPublishedEnd.EditValue = dtPlanningEnd.EditValue
timePublishedEnd.EditValue = New DateTime(timePlanningEnd.Time.TimeOfDay.Ticks)
txtCustomPublishedTotalUnits.Text = txtCustomPlannedTotalUnits.Text
End Sub
Then I click the OK:
Private Sub btnOK_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnOK.Click
' Required to check the appointment for conflicts.
If (Not controller.IsConflictResolved()) Then
Return
End If
' Save Planning
controller.DisplayStart = Me.dtPlanningStart.DateTime.Date + Me.timePlanningStart.Time.TimeOfDay
controller.DisplayEnd = Me.dtPlanningEnd.DateTime.Date + Me.timePlanningEnd.Time.TimeOfDay
controller.CustomPlannedRunRatePerShift = txtCustomPlanningRunRatePerShift.Text
' Save Published
controller.CustomPublishedStartDateTime = Me.dtPublishedStart.DateTime.Date + Me.timePublishedStart.Time.TimeOfDay
controller.CustomPublishedCompletedDateTime = Me.dtPublishedEnd.DateTime.Date + Me.timePublishedEnd.Time.TimeOfDay
controller.CustomPublishedPackagingLine = txtCustomPublishedPackagingLine.Text
controller.CustomPublishedRunRatePerShift = txtCustomPublishedRunRatePerShift.Text
controller.Description = rtbCustomJobNotes.Text
Try
' Save all changes of the editing appointment.
controller.ApplyChanges()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
When the code reaches controller.ApplyChanges() I get the following error:
FormatException occurred
Input sting was not in a correct format.
Troubleshooting tips:
When converting a string to a DateTime, parse the string to take the
date before putting each variable into the DateTime object.
...
I've tried DateTime.Parse, DateTime.ParseExact, Date.Parse, Date.ParseExact, assigning the date first then adding the time, and plenty of other things, but I just can't get past this.
How should I save the dates from the custom AppointmentEdit form back to the sql database. I was really hoping to use the custom appointment properties to make it simple.
I'm only worried about the Published Start and End date and times.

How to return an object from a recursed function?

I'm needing to go through all the controls on a page, looking for a specific one. We've got a bunch of user controls, a masterpage, content panel, &c.
The basic idea is simple, but once I find the control I want, say five 'layers' in, the control is returned only one level.
I know I can do something cheesy like having a private variable and assigning the control to that down in the rabbit hole, but I figure there must be a more official method of doing this.
Also, is this what is called tail recursion?
We're using the 3.5 framework.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim c As Control = getNamedControl(Page, "tb")
End Sub
Private Function getNamedControl(ByVal root As Control, ByVal theTarget As String) As Control
If root.Controls.Count < 1 Then
If Not IsNothing(root.ID) Then
If root.ID = theTarget Then
Return root
End If
End If
Else
For Each c As Control In root.Controls
If c.ID = theTarget Then
Return c
Else
getNamedControl(c, theTarget)
End If
Next
End If
End Function
Public Module WebControlExtensions
' Can be used to find controls recursively that won't be found via Page.FindControl
' because they are nested in other NamingContainers
' Example: Dim ctrl = Page.FindControlRecursive("tb") '
<Runtime.CompilerServices.Extension()>
Public Function FindControlRecursive(ByVal rootControl As Web.UI.Control, ByVal controlID As String) As Web.UI.Control
If rootControl.ID = controlID Then
Return rootControl
End If
For Each controlToSearch As Web.UI.Control In rootControl.Controls
Dim controlToReturn As Web.UI.Control = FindControlRecursive(controlToSearch, controlID)
If controlToReturn IsNot Nothing Then
Return controlToReturn
End If
Next
Return Nothing
End Function
End Module
The function will immediately return the control when it was found.
We've got a bunch of user controls, a masterpage, content panel...
Are you sure that it's a good idea to use a recursive function to find your controls? Especially if you use UserControls with the same ID in pages of the MasterPage's ContentPages, you would probably find the wrong control. This is very error-prone.
Besides you are hard-wiring your UserControls with their pages with their MasterPage, what is the opposite of encapsulation and reusability.
If c.ID = theTarget Then
Return c
Else
getNamedControl(c, theTarget)
End If
becomes:
If c.ID = theTarget Then
Return c
Else
Dim d as Control
d = getNamedControl(c, theTarget)
If Not IsNothing(d) Then
return d
End If
End If
Then just before ending the function:
return Null
EDIT:
assuming the return value is examined, this isn't tail recursion.
see: http://en.wikipedia.org/wiki/Tail_call
search for "foo3"