G
Guest
I am using code from Help with two exceptions. (1) I increased the number of sample rows from 3 to 20, and (2) I anchored the datagrid to bottom of form so that I can change the size of the grid by changing the size of the form
The code is at the following location in the January, 2004 help
ms-help://MS.VSCC.2003/MS.MSDNQTR.2004JAN.1033/cpref/html/frlrfSystemWindowsFormsDataGridClassTopic.ht
You can also find it by doing a search for "DataGrid Class", titles search only. It should show up as Rank #1
The problem occurs when I select a row at the bottom of the grid that is only 80% or so exposed height wise. If I select, Row1, the Debug window indicates that I selected Row #0 as I would expect. The same is true with I select any other row as long as it is fully displayed vertically in the grid.
If I select Row #10 that is only 50% exposed, instead of seeing Row = 9 in the debug window as I would expect, I see Row = 10. Needless to say this behavior is a problem when processing the selected row. Is there a workaround? One solution would be to only display complete rows in the grid rather than partial rows but I can't find a way to do it
For convenience, I am listing my entire code below, you can either paste it into a new form or start with code from help and make the two changes. Thank you very much for any assistance that you can provide
=============================
Option Explicit On
Option Strict O
Imports Syste
Imports System.ComponentMode
Imports System.Dat
Imports System.Drawin
Imports System.Windows.Form
Public Class Form
Inherits System.Windows.Forms.For
Private components As System.ComponentModel.Containe
Private WithEvents button1 As Butto
Private WithEvents button2 As Butto
Private WithEvents myDataGrid As DataGri
Private myDataSet As DataSe
Private TablesAlreadyAdded As Boolea
Public Sub New(
' Required for Windows Form Designer support
InitializeComponent(
' Call SetUp to bind the controls
SetUp(
End Su
Private Sub InitializeComponent(
Me.button1 = New System.Windows.Forms.Butto
Me.button2 = New System.Windows.Forms.Butto
Me.myDataGrid = New System.Windows.Forms.DataGri
CType(Me.myDataGrid, System.ComponentModel.ISupportInitialize).BeginInit(
Me.SuspendLayout(
'button
Me.button1.Location = New System.Drawing.Point(24, 16
Me.button1.Name = "button1
Me.button1.Size = New System.Drawing.Size(120, 24
Me.button1.TabIndex =
Me.button1.Text = "Change Appearance
'button
Me.button2.Location = New System.Drawing.Point(150, 16
Me.button2.Name = "button2
Me.button2.Size = New System.Drawing.Size(120, 24
Me.button2.TabIndex =
Me.button2.Text = "Get Binding Manager
'myDataGri
Me.myDataGrid.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom)
Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles
Me.myDataGrid.CaptionText = "Microsoft DataGrid Control
Me.myDataGrid.DataMember = "
Me.myDataGrid.HeaderForeColor = System.Drawing.SystemColors.ControlTex
Me.myDataGrid.Location = New System.Drawing.Point(24, 50
Me.myDataGrid.Name = "myDataGrid
Me.myDataGrid.Size = New System.Drawing.Size(300, 200
Me.myDataGrid.TabIndex =
'Form
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13
Me.ClientSize = New System.Drawing.Size(450, 330
Me.Controls.Add(Me.button1
Me.Controls.Add(Me.button2
Me.Controls.Add(Me.myDataGrid
Me.Name = "Form1
Me.Text = "DataGrid Control Sample
CType(Me.myDataGrid, System.ComponentModel.ISupportInitialize).EndInit(
Me.ResumeLayout(False
End Su
Public Shared Sub Main(
Application.Run(New Form1
End Su
Private Sub SetUp(
' Create a DataSet with two tables and one relation
MakeDataSet(
' Bind the DataGrid to the DataSet. The dataMembe
' specifies that the Customers table should be displayed
myDataGrid.SetDataBinding(myDataSet, "Customers"
End Su
Protected Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Clic
If TablesAlreadyAdded = True Then Exit Sub
AddCustomDataTableStyle()
End Sub
Private Sub AddCustomDataTableStyle()
Dim ts1 As New DataGridTableStyle
ts1.MappingName = "Customers"
' Set other properties.
ts1.AlternatingBackColor = Color.LightGray
' Add a GridColumnStyle and set its MappingName
' to the name of a DataColumn in the DataTable.
' Set the HeaderText and Width properties.
Dim boolCol As New DataGridBoolColumn
boolCol.MappingName = "Current"
boolCol.HeaderText = "IsCurrent Customer"
boolCol.Width = 150
ts1.GridColumnStyles.Add(boolCol)
' Add a second column style.
Dim TextCol As New DataGridTextBoxColumn
TextCol.MappingName = "custName"
TextCol.HeaderText = "Customer Name"
TextCol.Width = 250
ts1.GridColumnStyles.Add(TextCol)
' Create the second table style with columns.
Dim ts2 As New DataGridTableStyle
ts2.MappingName = "Orders"
' Set other properties.
ts2.AlternatingBackColor = Color.LightBlue
' Create new ColumnStyle objects
Dim cOrderDate As New DataGridTextBoxColumn
cOrderDate.MappingName = "OrderDate"
cOrderDate.HeaderText = "Order Date"
cOrderDate.Width = 100
ts2.GridColumnStyles.Add(cOrderDate)
' Use a PropertyDescriptor to create a formatted
' column. First get the PropertyDescriptorCollection
' for the data source and data member.
Dim pcol As PropertyDescriptorCollection = _
Me.BindingContext(myDataSet, "Customers.custToOrders"). _
GetItemProperties()
' Create a formatted column using a PropertyDescriptor.
' The formatting character "c" specifies a currency format. */
Dim csOrderAmount As _
New DataGridTextBoxColumn(pcol("OrderAmount"), "c", True)
csOrderAmount.MappingName = "OrderAmount"
csOrderAmount.HeaderText = "Total"
csOrderAmount.Width = 100
ts2.GridColumnStyles.Add(csOrderAmount)
' Add the DataGridTableStyle instances to
' the GridTableStylesCollection.
myDataGrid.TableStyles.Add(ts1)
myDataGrid.TableStyles.Add(ts2)
' Sets the TablesAlreadyAdded to true so this doesn't happen again.
TablesAlreadyAdded = True
End Sub
Protected Sub button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button2.Click
Dim bmGrid As BindingManagerBase
bmGrid = BindingContext(myDataSet, "Customers")
MessageBox.Show(("Current BindingManager Position: " & bmGrid.Position))
End Sub
Private Sub Grid_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles myDataGrid.MouseUp
' Create a HitTestInfo object using the HitTest method.
' Get the DataGrid by casting sender.
Dim myGrid As DataGrid = CType(sender, DataGrid)
Dim myHitInfo As DataGrid.HitTestInfo = myGrid.HitTest(e.X, e.Y)
Console.WriteLine(myHitInfo)
Console.WriteLine(myHitInfo.Type)
Console.WriteLine(myHitInfo.Row)
Console.WriteLine(myHitInfo.Column)
End Sub
' Create a DataSet with two tables and populate it.
Private Sub MakeDataSet()
' Create a DataSet.
myDataSet = New DataSet("myDataSet")
' Create two DataTables.
Dim tCust As New DataTable("Customers")
Dim tOrders As New DataTable("Orders")
' Create two columns, and add them to the first table.
Dim cCustID As New DataColumn("CustID", GetType(Integer))
Dim cCustName As New DataColumn("CustName")
Dim cCurrent As New DataColumn("Current", GetType(Boolean))
tCust.Columns.Add(cCustID)
tCust.Columns.Add(cCustName)
tCust.Columns.Add(cCurrent)
' Create three columns, and add them to the second table.
Dim cID As New DataColumn("CustID", GetType(Integer))
Dim cOrderDate As New DataColumn("orderDate", GetType(DateTime))
Dim cOrderAmount As New DataColumn("OrderAmount", GetType(Decimal))
tOrders.Columns.Add(cOrderAmount)
tOrders.Columns.Add(cID)
tOrders.Columns.Add(cOrderDate)
' Add the tables to the DataSet.
myDataSet.Tables.Add(tCust)
myDataSet.Tables.Add(tOrders)
' Create a DataRelation, and add it to the DataSet.
Dim dr As New DataRelation("custToOrders", cCustID, cID)
myDataSet.Relations.Add(dr)
' Populates the tables. For each customer and order,
' creates two DataRow variables.
Dim newRow1 As DataRow
Dim newRow2 As DataRow
' Create three customers in the Customers Table.
Dim i As Integer
For i = 1 To 30
newRow1 = tCust.NewRow()
newRow1("custID") = i
' Add the row to the Customers table.
tCust.Rows.Add(newRow1)
Next i
' Give each customer a distinct name.
tCust.Rows(0)("custName") = "Customer1"
tCust.Rows(1)("custName") = "Customer2"
tCust.Rows(2)("custName") = "Customer3"
' Give the Current column a value.
tCust.Rows(0)("Current") = True
tCust.Rows(1)("Current") = True
tCust.Rows(2)("Current") = False
' For each customer, create five rows in the Orders table.
For i = 1 To 3
Dim j As Integer
For j = 1 To 5
newRow2 = tOrders.NewRow()
newRow2("CustID") = i
newRow2("orderDate") = New DateTime(2001, i, j * 2)
newRow2("OrderAmount") = i * 10 + j * 0.1
' Add the row to the Orders table.
tOrders.Rows.Add(newRow2)
Next j
Next i
End Sub
End Class
The code is at the following location in the January, 2004 help
ms-help://MS.VSCC.2003/MS.MSDNQTR.2004JAN.1033/cpref/html/frlrfSystemWindowsFormsDataGridClassTopic.ht
You can also find it by doing a search for "DataGrid Class", titles search only. It should show up as Rank #1
The problem occurs when I select a row at the bottom of the grid that is only 80% or so exposed height wise. If I select, Row1, the Debug window indicates that I selected Row #0 as I would expect. The same is true with I select any other row as long as it is fully displayed vertically in the grid.
If I select Row #10 that is only 50% exposed, instead of seeing Row = 9 in the debug window as I would expect, I see Row = 10. Needless to say this behavior is a problem when processing the selected row. Is there a workaround? One solution would be to only display complete rows in the grid rather than partial rows but I can't find a way to do it
For convenience, I am listing my entire code below, you can either paste it into a new form or start with code from help and make the two changes. Thank you very much for any assistance that you can provide
=============================
Option Explicit On
Option Strict O
Imports Syste
Imports System.ComponentMode
Imports System.Dat
Imports System.Drawin
Imports System.Windows.Form
Public Class Form
Inherits System.Windows.Forms.For
Private components As System.ComponentModel.Containe
Private WithEvents button1 As Butto
Private WithEvents button2 As Butto
Private WithEvents myDataGrid As DataGri
Private myDataSet As DataSe
Private TablesAlreadyAdded As Boolea
Public Sub New(
' Required for Windows Form Designer support
InitializeComponent(
' Call SetUp to bind the controls
SetUp(
End Su
Private Sub InitializeComponent(
Me.button1 = New System.Windows.Forms.Butto
Me.button2 = New System.Windows.Forms.Butto
Me.myDataGrid = New System.Windows.Forms.DataGri
CType(Me.myDataGrid, System.ComponentModel.ISupportInitialize).BeginInit(
Me.SuspendLayout(
'button
Me.button1.Location = New System.Drawing.Point(24, 16
Me.button1.Name = "button1
Me.button1.Size = New System.Drawing.Size(120, 24
Me.button1.TabIndex =
Me.button1.Text = "Change Appearance
'button
Me.button2.Location = New System.Drawing.Point(150, 16
Me.button2.Name = "button2
Me.button2.Size = New System.Drawing.Size(120, 24
Me.button2.TabIndex =
Me.button2.Text = "Get Binding Manager
'myDataGri
Me.myDataGrid.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom)
Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles
Me.myDataGrid.CaptionText = "Microsoft DataGrid Control
Me.myDataGrid.DataMember = "
Me.myDataGrid.HeaderForeColor = System.Drawing.SystemColors.ControlTex
Me.myDataGrid.Location = New System.Drawing.Point(24, 50
Me.myDataGrid.Name = "myDataGrid
Me.myDataGrid.Size = New System.Drawing.Size(300, 200
Me.myDataGrid.TabIndex =
'Form
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13
Me.ClientSize = New System.Drawing.Size(450, 330
Me.Controls.Add(Me.button1
Me.Controls.Add(Me.button2
Me.Controls.Add(Me.myDataGrid
Me.Name = "Form1
Me.Text = "DataGrid Control Sample
CType(Me.myDataGrid, System.ComponentModel.ISupportInitialize).EndInit(
Me.ResumeLayout(False
End Su
Public Shared Sub Main(
Application.Run(New Form1
End Su
Private Sub SetUp(
' Create a DataSet with two tables and one relation
MakeDataSet(
' Bind the DataGrid to the DataSet. The dataMembe
' specifies that the Customers table should be displayed
myDataGrid.SetDataBinding(myDataSet, "Customers"
End Su
Protected Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Clic
If TablesAlreadyAdded = True Then Exit Sub
AddCustomDataTableStyle()
End Sub
Private Sub AddCustomDataTableStyle()
Dim ts1 As New DataGridTableStyle
ts1.MappingName = "Customers"
' Set other properties.
ts1.AlternatingBackColor = Color.LightGray
' Add a GridColumnStyle and set its MappingName
' to the name of a DataColumn in the DataTable.
' Set the HeaderText and Width properties.
Dim boolCol As New DataGridBoolColumn
boolCol.MappingName = "Current"
boolCol.HeaderText = "IsCurrent Customer"
boolCol.Width = 150
ts1.GridColumnStyles.Add(boolCol)
' Add a second column style.
Dim TextCol As New DataGridTextBoxColumn
TextCol.MappingName = "custName"
TextCol.HeaderText = "Customer Name"
TextCol.Width = 250
ts1.GridColumnStyles.Add(TextCol)
' Create the second table style with columns.
Dim ts2 As New DataGridTableStyle
ts2.MappingName = "Orders"
' Set other properties.
ts2.AlternatingBackColor = Color.LightBlue
' Create new ColumnStyle objects
Dim cOrderDate As New DataGridTextBoxColumn
cOrderDate.MappingName = "OrderDate"
cOrderDate.HeaderText = "Order Date"
cOrderDate.Width = 100
ts2.GridColumnStyles.Add(cOrderDate)
' Use a PropertyDescriptor to create a formatted
' column. First get the PropertyDescriptorCollection
' for the data source and data member.
Dim pcol As PropertyDescriptorCollection = _
Me.BindingContext(myDataSet, "Customers.custToOrders"). _
GetItemProperties()
' Create a formatted column using a PropertyDescriptor.
' The formatting character "c" specifies a currency format. */
Dim csOrderAmount As _
New DataGridTextBoxColumn(pcol("OrderAmount"), "c", True)
csOrderAmount.MappingName = "OrderAmount"
csOrderAmount.HeaderText = "Total"
csOrderAmount.Width = 100
ts2.GridColumnStyles.Add(csOrderAmount)
' Add the DataGridTableStyle instances to
' the GridTableStylesCollection.
myDataGrid.TableStyles.Add(ts1)
myDataGrid.TableStyles.Add(ts2)
' Sets the TablesAlreadyAdded to true so this doesn't happen again.
TablesAlreadyAdded = True
End Sub
Protected Sub button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button2.Click
Dim bmGrid As BindingManagerBase
bmGrid = BindingContext(myDataSet, "Customers")
MessageBox.Show(("Current BindingManager Position: " & bmGrid.Position))
End Sub
Private Sub Grid_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles myDataGrid.MouseUp
' Create a HitTestInfo object using the HitTest method.
' Get the DataGrid by casting sender.
Dim myGrid As DataGrid = CType(sender, DataGrid)
Dim myHitInfo As DataGrid.HitTestInfo = myGrid.HitTest(e.X, e.Y)
Console.WriteLine(myHitInfo)
Console.WriteLine(myHitInfo.Type)
Console.WriteLine(myHitInfo.Row)
Console.WriteLine(myHitInfo.Column)
End Sub
' Create a DataSet with two tables and populate it.
Private Sub MakeDataSet()
' Create a DataSet.
myDataSet = New DataSet("myDataSet")
' Create two DataTables.
Dim tCust As New DataTable("Customers")
Dim tOrders As New DataTable("Orders")
' Create two columns, and add them to the first table.
Dim cCustID As New DataColumn("CustID", GetType(Integer))
Dim cCustName As New DataColumn("CustName")
Dim cCurrent As New DataColumn("Current", GetType(Boolean))
tCust.Columns.Add(cCustID)
tCust.Columns.Add(cCustName)
tCust.Columns.Add(cCurrent)
' Create three columns, and add them to the second table.
Dim cID As New DataColumn("CustID", GetType(Integer))
Dim cOrderDate As New DataColumn("orderDate", GetType(DateTime))
Dim cOrderAmount As New DataColumn("OrderAmount", GetType(Decimal))
tOrders.Columns.Add(cOrderAmount)
tOrders.Columns.Add(cID)
tOrders.Columns.Add(cOrderDate)
' Add the tables to the DataSet.
myDataSet.Tables.Add(tCust)
myDataSet.Tables.Add(tOrders)
' Create a DataRelation, and add it to the DataSet.
Dim dr As New DataRelation("custToOrders", cCustID, cID)
myDataSet.Relations.Add(dr)
' Populates the tables. For each customer and order,
' creates two DataRow variables.
Dim newRow1 As DataRow
Dim newRow2 As DataRow
' Create three customers in the Customers Table.
Dim i As Integer
For i = 1 To 30
newRow1 = tCust.NewRow()
newRow1("custID") = i
' Add the row to the Customers table.
tCust.Rows.Add(newRow1)
Next i
' Give each customer a distinct name.
tCust.Rows(0)("custName") = "Customer1"
tCust.Rows(1)("custName") = "Customer2"
tCust.Rows(2)("custName") = "Customer3"
' Give the Current column a value.
tCust.Rows(0)("Current") = True
tCust.Rows(1)("Current") = True
tCust.Rows(2)("Current") = False
' For each customer, create five rows in the Orders table.
For i = 1 To 3
Dim j As Integer
For j = 1 To 5
newRow2 = tOrders.NewRow()
newRow2("CustID") = i
newRow2("orderDate") = New DateTime(2001, i, j * 2)
newRow2("OrderAmount") = i * 10 + j * 0.1
' Add the row to the Orders table.
tOrders.Rows.Add(newRow2)
Next j
Next i
End Sub
End Class