C#.NET 或 VB.NET Windows 窗体中的 DataGridView – 技巧、窍门和常见问题

发布于:2025-05-17 ⋅ 阅读:(12) ⋅ 点赞:(0)

        DataGridView 控件是一个 Windows 窗体控件,它允许您自定义和编辑表格数据。它提供了许多属性、方法和事件来自定义其外观和行为。在本文中,我们将讨论一些常见问题及其解决方案。这些问题来自各种来源,包括一些新闻组、MSDN 网站以及一些由我在 MSDN 论坛上解答的问题。

技巧 1 – 填充 DataGridView

        在这个简短的代码片段中,我们将使用 LoadData() 方法填充 DataGridView。此方法使用 SqlDataAdapter 填充 DataSet。然后将 DataSet 中的“Orders”表绑定到 BindingSource 组件,这使我们能够灵活地选择/修改数据位置。

C#

public partial class Form1 : Form
    {
        private SqlDataAdapter da;
        private SqlConnection conn;
        BindingSource bsource = new BindingSource();
        DataSet ds = null;
        string sql;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void btnLoad_Click(object sender, EventArgs e)
        {
            LoadData();
        }
 
        private void LoadData()
        {
string connectionString = "Data Source=localhost;Initial Catalog=Northwind;" + "Integrated Security=SSPI;";
            conn = new SqlConnection(connectionString);
sql = "SELECT OrderID, CustomerID, EmployeeID, OrderDate, Freight," + "ShipName, ShipCountry FROM Orders";
 
            da = new SqlDataAdapter(sql, conn);
            conn.Open();
            ds = new DataSet();
            SqlCommandBuilder commandBuilder = new SqlCommandBuilder(da);          
            da.Fill(ds, "Orders");
            bsource.DataSource = ds.Tables["Orders"];
            dgv.DataSource = bsource;          
        }
    }
    
VB.NET

Public Partial Class Form1
      Inherits Form
            Private da As SqlDataAdapter
            Private conn As SqlConnection
            Private bsource As BindingSource = New BindingSource()
            Private ds As DataSet = Nothing
            Private sql As String
 
            Public Sub New()
                  InitializeComponent()
            End Sub
 
Private Sub btnLoad_Click(ByVal sender As Object, ByVal e As EventArgs)
                  LoadData()
            End Sub
 
            Private Sub LoadData()
Dim connectionString As String = "Data Source=localhost;Initial Catalog=Northwind;" & "Integrated Security=SSPI;"
                  conn = New SqlConnection(connectionString)
sql = "SELECT OrderID, CustomerID, EmployeeID, OrderDate, Freight," & "ShipName, ShipCountry FROM Orders"
 
                  da = New SqlDataAdapter(sql, conn)
                  conn.Open()
                  ds = New DataSet()
Dim commandBuilder As SqlCommandBuilder = New SqlCommandBuilder(da)
                  da.Fill(ds, "Orders")
                  bsource.DataSource = ds.Tables("Orders")
                  dgv.DataSource = bsource
            End Sub
End Class

技巧 2 – 更新 DataGridView 中的数据并将更改保存到数据库中

        编辑单元格中的数据后,如果您想在数据库中永久更新更改,请使用以下代码:

C#

private void btnUpdate_Click(object sender, EventArgs e)
        {
            DataTable dt = ds.Tables["Orders"];
           this.dgv.BindingContext[dt].EndCurrentEdit();
            this.da.Update(dt);
        }
        
VB.NET

Private Sub btnUpdate_Click(ByVal sender As Object, ByVal e As EventArgs)
                  Dim dt As DataTable = ds.Tables("Orders")
                  Me.dgv.BindingContext(dt).EndCurrentEdit()
                  Me.da.Update(dt)
      End Sub

技巧3 – 在 DataGridView 中删除行之前显示确认框

        处理 UserDeletingRow 事件,向用户显示确认框。如果用户确认删除,则删除该行。如果用户点击“取消”,则设置 e.cancel = true,取消行删除。

C#

private void dgv_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            if (!e.Row.IsNewRow)
            {
                DialogResult res = MessageBox.Show("Are you sure you want to delete this row?", "Delete confirmation",
                         MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (res == DialogResult.No)
                    e.Cancel = true;
            }
        }
        
VB.NET

Private Sub dgv_UserDeletingRow(ByVal sender As Object, ByVal e As DataGridViewRowCancelEventArgs)
                  If (Not e.Row.IsNewRow) Then
                        Dim res As DialogResult = MessageBox.Show("Are you sure you want to delete this row?", "Delete confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                        If res = DialogResult.No Then
                              e.Cancel = True
                        End If
                  End If
End Sub

技巧 4 – 如何自动调整 DataGridView 中的列宽

        下面的代码片段首先自动调整列的大小以适应其内容。然后将 AutoSizeColumnsMode 设置为“DataGridViewAutoSizeColumnsMode.AllCells”枚举值,以便在数据发生变化时自动调整列的宽度。

C#

private void btnResize_Click(object sender, EventArgs e)
        {
            dgv.AutoResizeColumns();
            dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
 
        }
        
VB.NET

Private Sub btnResize_Click(ByVal sender As Object, ByVal e As EventArgs)
                  dgv.AutoResizeColumns()
                  dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
 
End Sub

技巧 5 - 在 DataGridView 中选择并突出显示整行

C#

int rowToBeSelected = 3; // third row
if (dgv.Rows.Count >= rowToBeSelected)
{             
       // Since index is zero based, you have to subtract 1
        dgv.Rows[rowToBeSelected - 1].Selected = true;
}

VB.NET

Dim rowToBeSelected As Integer = 3 ' third row
If dgv.Rows.Count >= rowToBeSelected Then
         ' Since index is zero based, you have to subtract 1
            dgv.Rows(rowToBeSelected - 1).Selected = True
End If

技巧 6 - 如何以编程方式滚动到 DataGridView 中的某一行

        DataGridView 有一个名为 FirstDisplayedScrollingRowIndex 的属性,可用于以编程方式滚动到某一行。

C#

int jumpToRow = 20;
if (dgv.Rows.Count >= jumpToRow && jumpToRow >= 1)
{             
        dgv.FirstDisplayedScrollingRowIndex = jumpToRow;
        dgv.Rows[jumpToRow].Selected = true;
}
 
VB.NET

Dim jumpToRow As Integer = 20
If dgv.Rows.Count >= jumpToRow AndAlso jumpToRow >= 1 Then
            dgv.FirstDisplayedScrollingRowIndex = jumpToRow
            dgv.Rows(jumpToRow).Selected = True
End If

技巧 7 - 计算 DataGridView 中的列总数并显示在文本框中

        一个常见的需求是计算货币字段的总计并将其显示在文本框中。在下面的代码片段中,我们将计算“运费”字段的总计。然后,我们将在显示数据的同时,通过格式化结果(观察ToString( "c" ) )将数据显示在文本框中,该文本框会显示特定于文化的货币。

C#

private void btnTotal_Click(object sender, EventArgs e)
        {
            if(dgv.Rows.Count > 0)
             txtTotal.Text = Total().ToString("c");
        }
 
        private double Total()
        {
            double tot = 0;
            int i = 0;
            for (i = 0; i < dgv.Rows.Count; i++)
            {
                tot = tot + Convert.ToDouble(dgv.Rows[i].Cells["Freight"].Value);
            }
            return tot;
        }
        
VB.NET

Private Sub btnTotal_Click(ByVal sender As Object, ByVal e As EventArgs)
                  If dgv.Rows.Count > 0 Then
                   txtTotal.Text = Total().ToString("c")
                  End If
End Sub
 
Private Function Total() As Double
                  Dim tot As Double = 0
                  Dim i As Integer = 0
                  For i = 0 To dgv.Rows.Count - 1
                        tot = tot + Convert.ToDouble(dgv.Rows(i).Cells("Freight").Value)
                  Next i
                  Return tot
End Function

技巧 8 - 更改 DataGridView 中的标题名称

        如果从数据库检索的列没有有意义的名称,我们始终可以选择更改标题名称,如下段所示:

C#

private void btnChange_Click(object sender, EventArgs e)
        {
            dgv.Columns[0].HeaderText = "MyHeader1";
            dgv.Columns[1].HeaderText = "MyHeader2";
        }
 
VB.NET

Private Sub btnChange_Click(ByVal sender As Object, ByVal e As EventArgs)
                  dgv.Columns(0).HeaderText = "MyHeader1"
                  dgv.Columns(1).HeaderText = "MyHeader2"
End Sub

技巧 9 - 更改 DataGridView 中单元格、行和边框的颜色

C#

private void btnCellRow_Click(object sender, EventArgs e)
        {
            // Change ForeColor of each Cell
            this.dgv.DefaultCellStyle.ForeColor = Color.Coral;
            // Change back color of each row
            this.dgv.RowsDefaultCellStyle.BackColor = Color.AliceBlue;
            // Change GridLine Color
            this.dgv.GridColor = Color.Blue;
            // Change Grid Border Style
            this.dgv.BorderStyle = BorderStyle.Fixed3D;
        }

VB.NET

Private Sub btnCellRow_Click(ByVal sender As Object, ByVal e As EventArgs)
                  ' Change ForeColor of each Cell
                  Me.dgv.DefaultCellStyle.ForeColor = Color.Coral
                  ' Change back color of each row
                  Me.dgv.RowsDefaultCellStyle.BackColor = Color.AliceBlue
                  ' Change GridLine Color
                  Me.dgv.GridColor = Color.Blue
                  ' Change Grid Border Style
                  Me.dgv.BorderStyle = BorderStyle.Fixed3D
End Sub

技巧 10 - 隐藏 DataGridView 中的列

        如果您想根据特定条件隐藏某一列,这里有一个代码片段。

C#

private void btnHide_Click(object sender, EventArgs e)
        {
            this.dgv.Columns["EmployeeID"].Visible = false;
        }

VB.NET

Private Sub btnHide_Click(ByVal sender As Object, ByVal e As EventArgs)
                  Me.dgv.Columns("EmployeeID").Visible = False
End Sub

技巧 11 - 处理 DataGridView 中 ComboBox 的 SelectedIndexChanged

        要处理 DataGridViewComboBox 的 SelectedIndexChanged 事件,您需要使用 DataGridView.EditingControlShowing 事件,如下所示。然后,您可以检索组合框的选定索引或选定文本。

C#

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            ComboBox editingComboBox = (ComboBox)e.Control;
            if(editingComboBox != null)
                editingComboBox.SelectedIndexChanged += new System.EventHandler(this.editingComboBox_SelectedIndexChanged);
        }
        
private void editingComboBox_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            ComboBox comboBox1 = (ComboBox)sender;
            // Display index
            MessageBox.Show(comboBox1.SelectedIndex.ToString());
            // Display value
            MessageBox.Show(comboBox1.Text);
        }

VB.NET

Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs)
                  Dim editingComboBox As ComboBox = CType(e.Control, ComboBox)
                  If Not editingComboBox Is Nothing Then
                        AddHandler editingComboBox.SelectedIndexChanged, AddressOf editingComboBox_SelectedIndexChanged
                  End If
End Sub
 
Private Sub editingComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
                  Dim comboBox1 As ComboBox = CType(sender, ComboBox)
                  ' Display index
                  MessageBox.Show(comboBox1.SelectedIndex.ToString())
                  ' Display value
                  MessageBox.Show(comboBox1.Text)
End Sub

技巧 12 - 更改 DataGridView 中交替行的颜色

C#

private void btnAlternate_Click(object sender, EventArgs e)
        {
            this.dgv.RowsDefaultCellStyle.BackColor = Color.White;
            this.dgv.AlternatingRowsDefaultCellStyle.BackColor = Color.Aquamarine;
        }

VB.NET

Private Sub btnAlternate_Click(ByVal sender As Object, ByVal e As EventArgs)
                  Me.dgv.RowsDefaultCellStyle.BackColor = Color.White
                  Me.dgv.AlternatingRowsDefaultCellStyle.BackColor = Color.Aquamarine
End Sub

技巧 13 - 在 DataGridView 中格式化数据

        DataGridView 公开了一些属性,使您能够格式化数据,例如以特定文化的货币显示货币列或以所需的格式显示空值等等。

C#

private void btnFormat_Click(object sender, EventArgs e)
        {
            // display currency in culture-specific currency for
            this.dgv.Columns["Freight"].DefaultCellStyle.Format = "c";
            // display nulls as 'NA'
            this.dgv.DefaultCellStyle.NullValue = "NA";
        }

VB.NET

Private Sub btnFormat_Click(ByVal sender As Object, ByVal e As EventArgs)
                  ' display currency in culture-specific currency for
                  Me.dgv.Columns("Freight").DefaultCellStyle.Format = "c"
                  ' display nulls as 'NA'
                  Me.dgv.DefaultCellStyle.NullValue = "NA"
End Sub

技巧 14 – 更改 DataGridView 中的列顺序

        要更改列的顺序,只需将 DataGridView 的 DisplayIndex 属性设置为所需的值。请记住,索引从零开始。

C#

private void btnReorder_Click(object sender, EventArgs e)
        {
             dgv.Columns["CustomerID"].DisplayIndex = 5;
             dgv.Columns["OrderID"].DisplayIndex = 3;
             dgv.Columns["EmployeeID"].DisplayIndex = 1;
             dgv.Columns["OrderDate"].DisplayIndex = 2;
             dgv.Columns["Freight"].DisplayIndex = 6;
             dgv.Columns["ShipCountry"].DisplayIndex = 0;
             dgv.Columns["ShipName"].DisplayIndex = 4;
        }

VB.NET

Private Sub btnReorder_Click(ByVal sender As Object, ByVal e As EventArgs)
                   dgv.Columns("CustomerID").DisplayIndex = 5
                   dgv.Columns("OrderID").DisplayIndex = 3
                   dgv.Columns("EmployeeID").DisplayIndex = 1
                   dgv.Columns("OrderDate").DisplayIndex = 2
                   dgv.Columns("Freight").DisplayIndex = 6
                   dgv.Columns("ShipCountry").DisplayIndex = 0
                   dgv.Columns("ShipName").DisplayIndex = 4
End Sub
 
我希望这篇文章对您有用,并感谢您的阅读。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。


网站公告

今日签到

点亮在社区的每一天
去签到