【发布时间】:2016-11-20 12:16:08
【问题描述】:
我在辅助TabPage 上有一个DataGridView,我希望在输入TabPage 时更新网格内的数据,但我不希望处理RowEnter 事件,除非用户实际点击了一行。在TabPage.Enter 事件触发后,网格中的第一行似乎是自动选择的,所以我无法抑制它。
显示问题的代码如下。我在运行时创建了控件,因此您可以复制粘贴,但在实际程序中我使用了设计器。
我希望看到的行为是,选择TabPage2后,DataGridView充满了数据,但TextBox1是空的,直到我点击一行。
Public Class Form1
Private WithEvents DataGridView1 As DataGridView
Private WithEvents TextBox1 As TextBox
Private WithEvents TabPage2 As TabPage
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
'Add controls to the form (usually I use the designer to do this)
Dim TabPage1 As New TabPage() With {.Name = "TabPage1", .Text = "TabPage1"}
TabPage2 = New TabPage() With {.Name = "TabPage2", .Text = "TabPage2"}
DataGridView1 = New DataGridView With {.Name = "DataGridView1", .SelectionMode = DataGridViewSelectionMode.FullRowSelect, .MultiSelect = False, .ReadOnly = True, .AllowUserToAddRows = False, .Size = New Size(TabPage1.Size.Width, TabPage2.Size.Height - 40), .Anchor = AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top Or AnchorStyles.Bottom, .TabIndex = 1}
TextBox1 = New TextBox With {.Name = "TextBox1", .Top = DataGridView1.Bottom + 5, .Width = DataGridView1.Width, .Visible = True, .Anchor = AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Bottom, .TabIndex = 0}
TabPage2.Controls.Add(TextBox1)
TabPage2.Controls.Add(DataGridView1)
Dim TabControl1 As New TabControl() With {.Name = "TabControl1"}
TabControl1.TabPages.Add(TabPage1)
TabControl1.TabPages.Add(TabPage2)
TabControl1.Size = Me.ClientRectangle.Size
TabControl1.Anchor = AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top Or AnchorStyles.Bottom
Me.Controls.Add(TabControl1)
End Sub
Private Sub DataGridView1_RowEnter(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.RowEnter
'I would like the textbox to fill ONLY after the user has selected a row in DataGridView1.
'The problem I am having is that the first row auto-selects once I enter the tab
Dim drw As DataRow = DirectCast(DataGridView1.Rows(e.RowIndex).DataBoundItem, DataRowView).Row
TextBox1.Text = CStr(drw(1))
End Sub
Private Sub TabPage2_Enter(sender As Object, e As EventArgs) Handles TabPage2.Enter
RefreshGrid() 'Refresh the data in the list
End Sub
Sub RefreshGrid()
'simulate a database query
DataGridView1.DataSource = Nothing
Dim dtb As New DataTable
dtb.Columns.Add("C1")
dtb.Columns.Add("C2")
dtb.Rows.Add("1", "One")
dtb.Rows.Add("2", "Two")
dtb.Rows.Add("3", "Three")
dtb.Rows.Add("4", "Four")
dtb.Rows.Add("5", "Five")
DataGridView1.DataSource = dtb
End Sub
End Class
【问题讨论】:
-
当您选择
TabPage时,该页面上Tab 顺序中的第一个控件将获得焦点。如果您的网格是第一个控件,那么它将获得焦点。如果它是唯一的控件,那么您别无选择,只能让它获得焦点。 -
好的,我已经更新为每个控件设置
.TabIndex,但问题仍然存在。我认为DataGridView在收到焦点时不会更改所选行。我认为DataGridView在初始化时设置了选择。 (事实上,TabPage本身在你点击时会保持焦点) -
这完全取决于您所说的“选定”。在
DataGridView控件中,selected 实际上意味着它被突出显示并且与任何RowEnter事件无关。RowEnter只会在一行成为当前行时引发,即包含当前单元格的行。可以将CurrentCell设置为Nothing,并且在网格获得焦点之前它将保持Nothing。 -
谢谢。 “选定”是指用户单击一行以使其成为当前行。我尝试将
DataGridView1.CurrentCell = Nothing添加到TabPage2_Enter的末尾,但RowEnter事件仍然会触发。 -
我会使用点击事件并获取被点击的行。
标签: vb.net events datagridview tabcontrol tabpage