Currently I am working on a project that is using a datagridview with a custom addition that allows a user to select a date using a calender.
I found out how to do this at http://msdn.microsoft.com/en-us/library/7tas5c80.aspx. My current problem is I would like to use the .Cellclick event that datagridviews have to offer.
I have set up my code as the following:
Create a class:
Code:Imports System Imports System.Windows.Forms Public Class CalendarColumn Inherits DataGridViewColumn Public Sub New() MyBase.New(New CalendarCell()) End Sub Public Overrides Property CellTemplate() As DataGridViewCell Get Return MyBase.CellTemplate End Get Set(ByVal value As DataGridViewCell) ' Ensure that the cell used for the template is a CalendarCell. If (value IsNot Nothing) AndAlso _ Not value.GetType().IsAssignableFrom(GetType(CalendarCell)) _ Then Throw New InvalidCastException("Must be a CalendarCell") End If MyBase.CellTemplate = value End Set End Property End Class Public Class CalendarCell Inherits DataGridViewTextBoxCell Public Sub New() ' Use the short date format. Me.Style.Format = "d" End Sub Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, _ ByVal initialFormattedValue As Object, _ ByVal dataGridViewCellStyle As DataGridViewCellStyle) ' Set the value of the editing control to the current cell value. MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, _ dataGridViewCellStyle) Dim ctl As CalendarEditingControl = _ CType(DataGridView.EditingControl, CalendarEditingControl) ' Use the default row value when Value property is null. If (Me.Value Is Nothing) Then ctl.Value = CType(Me.DefaultNewRowValue, DateTime) Else ctl.Value = CType(Me.Value, DateTime) End If End Sub Public Overrides ReadOnly Property EditType() As Type Get ' Return the type of the editing control that CalendarCell uses. Return GetType(CalendarEditingControl) End Get End Property Public Overrides ReadOnly Property ValueType() As Type Get ' Return the type of the value that CalendarCell contains. Return GetType(DateTime) End Get End Property Public Overrides ReadOnly Property DefaultNewRowValue() As Object Get ' Use the current date and time as the default value. Return DateTime.Now End Get End Property End Class Class CalendarEditingControl Inherits DateTimePicker Implements IDataGridViewEditingControl Private dataGridViewControl As DataGridView Private valueIsChanged As Boolean = False Private rowIndexNum As Integer Public Sub New() Me.Format = DateTimePickerFormat.Short End Sub Public Property EditingControlFormattedValue() As Object _ Implements IDataGridViewEditingControl.EditingControlFormattedValue Get Return Me.Value.ToShortDateString() End Get Set(ByVal value As Object) Try ' This will throw an exception of the string is ' null, empty, or not in the format of a date. Me.Value = DateTime.Parse(CStr(value)) Catch ' In the case of an exception, just use the default ' value so we're not left with a null value. Me.Value = DateTime.Now End Try End Set End Property Public Function GetEditingControlFormattedValue(ByVal context _ As DataGridViewDataErrorContexts) As Object _ Implements IDataGridViewEditingControl.GetEditingControlFormattedValue Return Me.Value.ToShortDateString() End Function Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As _ DataGridViewCellStyle) _ Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl Me.Font = dataGridViewCellStyle.Font Me.CalendarForeColor = dataGridViewCellStyle.ForeColor Me.CalendarMonthBackground = dataGridViewCellStyle.BackColor End Sub Public Property EditingControlRowIndex() As Integer _ Implements IDataGridViewEditingControl.EditingControlRowIndex Get Return rowIndexNum End Get Set(ByVal value As Integer) rowIndexNum = value End Set End Property Public Function EditingControlWantsInputKey(ByVal key As Keys, _ ByVal dataGridViewWantsInputKey As Boolean) As Boolean _ Implements IDataGridViewEditingControl.EditingControlWantsInputKey ' Let the DateTimePicker handle the keys listed. Select Case key And Keys.KeyCode Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, _ Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp Return True Case Else Return Not dataGridViewWantsInputKey End Select End Function Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) _ Implements IDataGridViewEditingControl.PrepareEditingControlForEdit ' No preparation needs to be done. End Sub Public ReadOnly Property RepositionEditingControlOnValueChange() _ As Boolean Implements _ IDataGridViewEditingControl.RepositionEditingControlOnValueChange Get Return False End Get End Property Public Property EditingControlDataGridView() As DataGridView _ Implements IDataGridViewEditingControl.EditingControlDataGridView Get Return dataGridViewControl End Get Set(ByVal value As DataGridView) dataGridViewControl = value End Set End Property Public Property EditingControlValueChanged() As Boolean _ Implements IDataGridViewEditingControl.EditingControlValueChanged Get Return valueIsChanged End Get Set(ByVal value As Boolean) valueIsChanged = value End Set End Property Public ReadOnly Property EditingControlCursor() As Cursor _ Implements IDataGridViewEditingControl.EditingPanelCursor Get Return MyBase.Cursor End Get End Property Protected Overrides Sub OnValueChanged(ByVal eventargs As EventArgs) ' Notify the DataGridView that the contents of the cell have changed. valueIsChanged = True Me.EditingControlDataGridView.NotifyCurrentCellDirty(True) MyBase.OnValueChanged(eventargs) End Sub End Class
This is what I do with it so far in code:
As you can see I do not physically put the datagrid on there I let the code create it, the problem I was having when I did actually put a data grid on the for is the dates where not working properly. They seem to work fine when I do it this way, but the section of code I have commented out is what I need to add in to make my project complete. ( I drive the ability for users to be able to Add\Edit\Update\Delete my rows from the buttons".Code:#Region "GRD Account" Private Sub CreateDataGrdAccount() Me.Controls.Add(grdaccount) With grdaccount .Columns.Add(New DataGridViewTextBoxColumn) .Columns.Add(New CalendarColumn) .Columns.Add(New DataGridViewComboBoxColumn) .Columns.Add(New DataGridViewTextBoxColumn) .Columns.Add(New DataGridViewTextBoxColumn) .Columns.Add(New CalendarColumn) .Columns.Add(New CalendarColumn) .Columns.Add(New DataGridViewTextBoxColumn) .Columns.Add(New DataGridViewButtonColumn) .Columns.Add(New DataGridViewButtonColumn) .Columns(0).Name = "Entry Number" .Columns(1).Name = "Date Entered" .Columns(2).Name = "Desciption" .Columns(3).Name = "Deposit" .Columns(4).Name = "Withdrawal" .Columns(5).Name = "Date Processing" .Columns(6).Name = "Date Processed" .Columns(7).Name = "Balance" .Columns(8).Name = "Options" .Columns(9).Name = "Options" .AllowUserToAddRows = False .AllowUserToDeleteRows = False .AllowUserToOrderColumns = False .AllowUserToResizeColumns = False .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells .BackgroundColor = Color.FromKnownColor(KnownColor.Control) .BorderStyle = BorderStyle.None .CellBorderStyle = DataGridViewCellBorderStyle.Single .ClipboardCopyMode = DataGridViewClipboardCopyMode.Disable .ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single .ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Raised .EditMode = DataGridViewEditMode.EditProgrammatically .Enabled = True .MultiSelect = False .ReadOnly = True .RowHeadersVisible = False .ScrollBars = ScrollBars.Both .SelectionMode = DataGridViewSelectionMode.FullRowSelect .ShowCellErrors = False .ShowCellToolTips = False .ShowEditingIcon = False .ShowRowErrors = False .AlternatingRowsDefaultCellStyle.BackColor = Color.Silver .AlternatingRowsDefaultCellStyle.SelectionForeColor = Color.LightBlue .RowHeadersDefaultCellStyle.BackColor = Color.White .RowHeadersDefaultCellStyle.SelectionForeColor = Color.LightBlue .BringToFront() ' .Location = New Point(-4, -3) .Location = New Point(5, 25) .RowCount = 1 End With GrdAccoutnSetsize() grdAccountNewRow() End Sub Private Sub grdAccountNewRow() grdAccountEditrow(0, 3, "0") grdAccountEditrow(0, 4, "0") grdAccountEditrow(0, 5, String.Empty) grdAccountEditrow(0, 6, String.Empty) grdAccountEditrow(0, 8, GRDEDIT) grdAccountEditrow(0, 9, GRDDONTADD) End Sub Private Sub grdAccountEditrow(ByVal iItem As Integer, ByVal iCells As Integer, ByVal sValue As String) grdAccount.Rows.Item(iItem).Cells(iCells).Value = sValue End Sub Private Sub GrdAccoutnSetsize() grdAccount.Height = tpgAccount.Height grdAccount.Width = splContainer.Panel1.Width - pnlTab1.Width End Sub 'Private Sub grdAccount_CellClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdaccount.CellClick ' Dim cNotAllowedChars() As Char = "089".ToCharArray ' Try ' Select Case grdAccount.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString ' Case GRDADD ' For iCellCount As Integer = 0 To grdAccount.ColumnCount - 1 ' If iCellCount.ToString.Contains(cNotAllowedChars) = False Then ' ' End If 'Next ' Case GRDDELETE ' grdAccount.Rows.RemoveAt(e.RowIndex)' ' Case GRDDONTADD ' For iCellCount As Integer = 0 To grdAccount.ColumnCount - 1 ' If iCellCount.ToString.Contains(cNotAllowedChars) = False Then ' grdAccount.Rows(e.RowIndex).Cells(iCellCount).Value = Nothing ' End If ' Next ' Case GRDEDIT ' Try ' grdAccount.Rows(e.RowIndex).Cells(7).Value.ToString() ' grdAccount.Rows(e.RowIndex).Cells(8).Value = GRDEDIT ' Catch ex As Exception ' grdAccount.Rows(e.RowIndex).Cells(8).Value = GRDADD ' Finally ' ' grdAccount.SelectionMode = DataGridViewSelectionMode.CellSelect ' ' grdAccount.Rows(e.RowIndex).ReadOnly = False ' End Try ' End Select ' Catch ex As Exception ' ' End Try 'End Sub #End Region
Could someone please help me figure out how to be able to use the cellclick event with my custom calender?
Thanks.


Reply With Quote
