Thursday, July 3, 2008

How to Check Mouse Buttons State

Level: Beginner

Description:
Sometimes it is required to check the Mouse Button state on a certain point. For this purpose we use MouseButtons shared property,

System.Windows.Forms.Form.MouseButtons

Example: in DataGridView SelectionChanged event handler we can determine whether the selection is changed through mouse or not.

Private Sub DataGridView1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView1.SelectionChanged
If System.Windows.Forms.Form.MouseButtons = Windows.Forms.MouseButtons.Left Then
' Selection is Changed by mouse
Else
' Selection is NOT Changed by mouse
End If
End Sub

Making Enter Key, Move to Next Cell/Column in DataGridView After Cell Edit

This article explains how we can customize the DataGridView control so that when Enter Key is pressed then cursor (current selection) move to next cell / column after Cell Edit. Level: Intermediate Knowledge Required: DataGridView Description: By default in DataGridView control, when we press Enter Key to stop the editing in Current Cell, cursor moves to next Row and the current row is saved. This style is adopted from Excel, users working on Excel feel no problem with this. But users who worked in older applications do NOT like this type of editing. What they want is when Enter Key is pressed then Cursor should move to next cell / column. In DataGridView control we need to press TAB key to achieve this. Now we are going to customize the DataGridView control, so that when User Stop the Editing in Current Cell by pressing Enter Key then cursor should move in next cell / column. To understand the solution first note the followings, 1) When user presses enter key to stop the Editing, DataGridView CellEndEdit event occurs 2) Then cursor (current selection) moves to next row, on this point SelectionChanged event occurs To achieve this I have used a logic, 1) When CellEndEdit event occurs, I note the Cell which was Edited 2) Then in SelectionChanged event, I first check if this event is occured after the Editing, then I set the cursor (current selection) in the same row but next column of last edited cell Here I have created a customized control which is actually inherited from DataGridView control, and have added this functionality.
Public Class DataGridViewEnterMoveNext
    Inherits DataGridView

    Dim celWasEndEdit As DataGridViewCell
    Private _EnterMoveNext As Boolean = True

    <System.ComponentModel.DefaultValue(True)> _
    Public Property OnEnterKeyMoveNext() As Boolean
        Get
            Return Me._EnterMoveNext
        End Get
        Set(ByVal value As Boolean)
            Me._EnterMoveNext = value
        End Set
    End Property

    Private Sub DataGridView_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Me.CellEndEdit
        Me.celWasEndEdit = Me(e.ColumnIndex, e.RowIndex)
    End Sub

    Private Sub DataGridView_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SelectionChanged
        ' if Enter Move Next should work andalso
        '    mouse button was NOT down
        ' we are checking mouse buttons because if select was changed
        ' by Mouse then we will NOT do our Enter Move Next
        If Me._EnterMoveNext AndAlso MouseButtons = 0 Then
            ' if selection is changed after Cell Editing
            If Me.celWasEndEdit IsNot Nothing AndAlso _
               Me.CurrentCell IsNot Nothing Then
                ' if we are currently in the next line of last edit cell
                If Me.CurrentCell.RowIndex = Me.celWasEndEdit.RowIndex + 1 AndAlso _
                   Me.CurrentCell.ColumnIndex = Me.celWasEndEdit.ColumnIndex Then
                    Dim iColNew As Integer
                    Dim iRowNew As Integer
                    ' if we at the last column
                    If Me.celWasEndEdit.ColumnIndex >= Me.ColumnCount - 1 Then
                        iColNew = 0                         ' move to first column
                        iRowNew = Me.CurrentCell.RowIndex   ' and move to next row
                    Else ' else it means we are NOT at the last column
                        ' move to next column
                        iColNew = Me.celWasEndEdit.ColumnIndex + 1
                        ' but row should remain same
                        iRowNew = Me.celWasEndEdit.RowIndex
                    End If
                    Me.CurrentCell = Me(iColNew, iRowNew)   ' ok set the current column
                End If
            End If
            Me.celWasEndEdit = Nothing                      ' reset the cell end edit
        End If
    End Sub
End Class
Note that I have added a property OnEnterKeyMoveNext if this property is True then our customization will work otherwise NOT. Limitations: As you can see when user presses enter key, the row will be first saved in DataGridView control (ultimately the Source of DataGridView is updated), at this point if one or more columns are NOT allowed to have NULL values then our customization will NOT work properly. Since exception will be thrown and the row will be deleted. To overcome this issue we can set the AllowDBNull = False in our DataTable (which is bind with DataGridView) and use the custom validation as discussed in my previous post. How to add Column/Row Validation Using Typed DataTable Download Source Code: DataGridViewEnterAsTab.Zip See Also: DataGridView control FAQs and Quick Tips Paste Text in DataGridView Control (Bound with BindingSource)

Wednesday, July 2, 2008

Changing Connection String in TableAdapter

This article describes a way to change a Connection String in TableAdapter

Level: Intermediate

Knowledge Required:
  • Typed DataSet
  • TableAdapter
  • Partial Class
  • Project Settings
Description:
As we have used the DataSet Designer from Visual Studio, to create a Typed DataSet. Usually our Typed DataSet contains TableAdapter which interacts with Physical Database. When we first time add Typed DataSet using DataSet Designer, it adds a Connection String in the Project Setting. This connection string is by default accessed by the TableAdapter. Note that the connection string in Project Setting is defined with Scope = Application, which makes it a read-only property, therefore cannot be changed from code.

But sometimes it is required to change the Connection String, for example if different users log in the software then connection string will be different for each user with respect to their Login IDs and Passwords.

So to resolve this issue we can directly access the Connection property of TableAdapter to set the ConnectionString.

MyTableAdapter.Connection.ConnectionString = "...."

But another approach is to modify the TableAdapter using Partial Class and add methods that shall allow us change the Connection String, example,

Namespace CityDataSetTableAdapters
Partial Class CityTableAdapter
Public Sub New(ByVal sConStr As String)
Me.New()
Me.Connection.ConnectionString = sConStr
End Sub

Public Sub SetNewConnectionString(ByVal sConStr As String)
Me.Connection.ConnectionString = sConStr
End Sub
End Class
End Namespace

Now we can create another Setting in our Project with Scope = User and then we will change this setting according to current login in our code.



Usage:
Dim adpCity As CityDataSetTableAdapters.CityTableAdapter
Dim tblCity As CityDataSet.CityDataTable

My.Settings.MyConnectionString = "Data Source=.;Initial Catalog=MyDatabase;Persist Security Info=True;User ID=user;Password=password"
adpCity = New CityDataSetTableAdapters.CityTableAdapter(My.Settings.MyConnectionString)
tblCity = adpCity.GetData()
Debug.Print(tblCity.Count)

Tuesday, July 1, 2008

Using DateTimePicker Control to Take Year Input


Level: Beginner

Description:
While creating the User Interface (UI) we need to create a control which can take Year input. For this purpose we can use NumericUpDown control or can use just simple TextBox. But all these controls may require more coding to validate a Year.

DateTimePicker control reduces our work in this type of scenario. We can customize the look and feel of this control to fulfill our UI need. To setup change the following properties in Design View,

Format = Custom
CustomFormat = yyyy
ShowUpDown = True

Now we can check which Year is selected in our code as,

Dim intSelectedYear As Integer
intSelectedYear = Me.DateTimePicker1.Value.Year