Results 1 to 6 of 6

Thread: [RESOLVED] Help with custom Datagridview click event

  1. #1
    Member
    Join Date
    Aug 11
    Posts
    47

    Resolved [RESOLVED] Help with custom Datagridview click event

    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:
    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
    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".

    Could someone please help me figure out how to be able to use the cellclick event with my custom calender?

    Thanks.

  2. #2
    PowerPoster stanav's Avatar
    Join Date
    Jul 06
    Location
    Providence, RI - USA
    Posts
    9,167

    Re: Help with custom Datagridview click event

    What happens if you uncomment the commented code? And what's the desired/expected behavior?
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  3. #3
    PowerPoster dunfiddlin's Avatar
    Join Date
    Jun 12
    Posts
    5,471

    Re: Help with custom Datagridview click event

    If you're adding the control programmatically, don't you just need to add the appropriate event handler?

  4. #4
    Member
    Join Date
    Aug 11
    Posts
    47

    Re: Help with custom Datagridview click event

    If you un comment the code you recieve a blue squiggly under the word "grdaccount" . The message it gives is "Handles clauses requres a withevents variable defined in the containg type or one of its base types.

    Alls it really is suppose to do is let me know where the users has clicked on the data gridview. So I will know IE what row and and column they are clicking. I've tried to detect them through other mouse clicks but have yet to succeed.


    How would I go about adding the appropriate event handler? Would it be System.Windows.Forms.DataGridViewCellEventArgs? I will try and look into this.


    thanks

  5. #5
    PowerPoster stanav's Avatar
    Join Date
    Jul 06
    Location
    Providence, RI - USA
    Posts
    9,167

    Re: Help with custom Datagridview click event

    Do do you declare grdaccount? If you declare and create it dynamically, you can choose either of these two options:
    1. Declare it WithEvents and then attach it to the event handler using the Handles clause
    Code:
    Private WithEvents grdaccount As New DataGridView ' <<< declare the DGV withevents
    '.........
    'Attach cellclick event handler to it 
    Private Sub grdAccount_CellClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grdaccount.CellClick
       '.... code here
    End Sub
    2. If you don't declare it with events, you can use AddHandler to attach an event handler to it
    Code:
    Private grdaccount As New DataGridView ' <<< declare the DGV without events
    '.........
    'Attach cellclick event handler to it when you add columns
    Private Sub CreateDataGrdAccount()
        Me.Controls.Add(grdaccount)
        AddHandler grdaccount.CellClick, AddressOf(grdAccount_CellClick)
        '....
    End Sub
    'And the event handler doesn't need the Handles clause
    Private Sub grdAccount_CellClick(sender As Object, e As System.Windows.Forms.DataGridViewCellEventArgs)
       '.... code here
    End Sub
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

  6. #6
    Member
    Join Date
    Aug 11
    Posts
    47

    Re: Help with custom Datagridview click event

    thanks! Works perfect now.. I had it declared at the top but did not have the "Withevents" . Learning something new everyday.. Thanks again

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •