演练:创建未绑定 Windows 窗体 DataGridView 控件

你可能经常希望显示并非源自数据库的表格数据。 例如,你可能希望显示二维字符串数组的内容。 DataGridView 类提供了一种简单且高度可自定义的方式来显示数据,而无需绑定到数据源。 本演练演示了如何填充 DataGridView 控件并在“未绑定”模式下管理行的添加和删除。 默认情况下,用户可以添加新行。 若要防止添加行,请将 AllowUserToAddRows 属性设置为 false

若要将本主题中的代码复制为单个列表,请参阅如何:创建未绑定的 Windows 窗体 DataGridView 控件

创建窗体

使用未绑定的 DataGridView 控件

  1. 创建一个派生自 Form 并包含以下变量声明和 Main 方法的类。

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    public class Form1 : System.Windows.Forms.Form
    {
        private Panel buttonPanel = new Panel();
        private DataGridView songsDataGridView = new DataGridView();
        private Button addNewRowButton = new Button();
        private Button deleteRowButton = new Button();
    
    Imports System.Drawing
    Imports System.Windows.Forms
    
    Public Class Form1
        Inherits System.Windows.Forms.Form
    
        Private buttonPanel As New Panel
        Private WithEvents songsDataGridView As New DataGridView
        Private WithEvents addNewRowButton As New Button
        Private WithEvents deleteRowButton As New Button
    
    
        [STAThreadAttribute()]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new Form1());
        }
    }
    
    
        <STAThreadAttribute()> _
        Public Shared Sub Main()
            Application.EnableVisualStyles()
            Application.Run(New Form1())
        End Sub
    
    End Class
    
  2. 在窗体的类定义中实现 SetupLayout 方法以设置窗体的布局。

    private void SetupLayout()
    {
        this.Size = new Size(600, 500);
    
        addNewRowButton.Text = "Add Row";
        addNewRowButton.Location = new Point(10, 10);
        addNewRowButton.Click += new EventHandler(addNewRowButton_Click);
    
        deleteRowButton.Text = "Delete Row";
        deleteRowButton.Location = new Point(100, 10);
        deleteRowButton.Click += new EventHandler(deleteRowButton_Click);
    
        buttonPanel.Controls.Add(addNewRowButton);
        buttonPanel.Controls.Add(deleteRowButton);
        buttonPanel.Height = 50;
        buttonPanel.Dock = DockStyle.Bottom;
    
        this.Controls.Add(this.buttonPanel);
    }
    
    Private Sub SetupLayout()
    
        Me.Size = New Size(600, 500)
    
        With addNewRowButton
            .Text = "Add Row"
            .Location = New Point(10, 10)
        End With
    
        With deleteRowButton
            .Text = "Delete Row"
            .Location = New Point(100, 10)
        End With
    
        With buttonPanel
            .Controls.Add(addNewRowButton)
            .Controls.Add(deleteRowButton)
            .Height = 50
            .Dock = DockStyle.Bottom
        End With
    
        Me.Controls.Add(Me.buttonPanel)
    
    End Sub
    
  3. 创建一个 SetupDataGridView 方法来设置 DataGridView 列和属性。

    此方法首先将 DataGridView 控件添加到窗体的 Controls 集合中。 接下来,使用 ColumnCount 属性设置要显示的列数。 通过设置 ColumnHeadersDefaultCellStyle 属性返回的 DataGridViewCellStyleBackColorForeColorFont 属性来设置列标题的默认样式。

    设置布局和外观属性,然后分配列名。 当此方法退出时,DataGridView 控件已准备好填充。

    private void SetupDataGridView()
    {
        this.Controls.Add(songsDataGridView);
    
        songsDataGridView.ColumnCount = 5;
    
        songsDataGridView.ColumnHeadersDefaultCellStyle.BackColor = Color.Navy;
        songsDataGridView.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
        songsDataGridView.ColumnHeadersDefaultCellStyle.Font =
            new Font(songsDataGridView.Font, FontStyle.Bold);
    
        songsDataGridView.Name = "songsDataGridView";
        songsDataGridView.Location = new Point(8, 8);
        songsDataGridView.Size = new Size(500, 250);
        songsDataGridView.AutoSizeRowsMode =
            DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders;
        songsDataGridView.ColumnHeadersBorderStyle =
            DataGridViewHeaderBorderStyle.Single;
        songsDataGridView.CellBorderStyle = DataGridViewCellBorderStyle.Single;
        songsDataGridView.GridColor = Color.Black;
        songsDataGridView.RowHeadersVisible = false;
    
        songsDataGridView.Columns[0].Name = "Release Date";
        songsDataGridView.Columns[1].Name = "Track";
        songsDataGridView.Columns[2].Name = "Title";
        songsDataGridView.Columns[3].Name = "Artist";
        songsDataGridView.Columns[4].Name = "Album";
        songsDataGridView.Columns[4].DefaultCellStyle.Font =
            new Font(songsDataGridView.DefaultCellStyle.Font, FontStyle.Italic);
    
        songsDataGridView.SelectionMode =
            DataGridViewSelectionMode.FullRowSelect;
        songsDataGridView.MultiSelect = false;
        songsDataGridView.Dock = DockStyle.Fill;
    
        songsDataGridView.CellFormatting += new
            DataGridViewCellFormattingEventHandler(
            songsDataGridView_CellFormatting);
    }
    
    Private Sub SetupDataGridView()
    
        Me.Controls.Add(songsDataGridView)
    
        songsDataGridView.ColumnCount = 5
        With songsDataGridView.ColumnHeadersDefaultCellStyle
            .BackColor = Color.Navy
            .ForeColor = Color.White
            .Font = New Font(songsDataGridView.Font, FontStyle.Bold)
        End With
    
        With songsDataGridView
            .Name = "songsDataGridView"
            .Location = New Point(8, 8)
            .Size = New Size(500, 250)
            .AutoSizeRowsMode = _
                DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
            .ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single
            .CellBorderStyle = DataGridViewCellBorderStyle.Single
            .GridColor = Color.Black
            .RowHeadersVisible = False
    
            .Columns(0).Name = "Release Date"
            .Columns(1).Name = "Track"
            .Columns(2).Name = "Title"
            .Columns(3).Name = "Artist"
            .Columns(4).Name = "Album"
            .Columns(4).DefaultCellStyle.Font = _
                New Font(Me.songsDataGridView.DefaultCellStyle.Font, FontStyle.Italic)
    
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .MultiSelect = False
            .Dock = DockStyle.Fill
        End With
    
    End Sub
    
  4. 创建一个 PopulateDataGridView 方法以向 DataGridView 控件添加行。

    每行代表一首歌曲及其相关信息。

    private void PopulateDataGridView()
    {
    
        string[] row0 = { "11/22/1968", "29", "Revolution 9",
            "Beatles", "The Beatles [White Album]" };
        string[] row1 = { "1960", "6", "Fools Rush In",
            "Frank Sinatra", "Nice 'N' Easy" };
        string[] row2 = { "11/11/1971", "1", "One of These Days",
            "Pink Floyd", "Meddle" };
        string[] row3 = { "1988", "7", "Where Is My Mind?",
            "Pixies", "Surfer Rosa" };
        string[] row4 = { "5/1981", "9", "Can't Find My Mind",
            "Cramps", "Psychedelic Jungle" };
        string[] row5 = { "6/10/2003", "13",
            "Scatterbrain. (As Dead As Leaves.)",
            "Radiohead", "Hail to the Thief" };
        string[] row6 = { "6/30/1992", "3", "Dress", "P J Harvey", "Dry" };
    
        songsDataGridView.Rows.Add(row0);
        songsDataGridView.Rows.Add(row1);
        songsDataGridView.Rows.Add(row2);
        songsDataGridView.Rows.Add(row3);
        songsDataGridView.Rows.Add(row4);
        songsDataGridView.Rows.Add(row5);
        songsDataGridView.Rows.Add(row6);
    
        songsDataGridView.Columns[0].DisplayIndex = 3;
        songsDataGridView.Columns[1].DisplayIndex = 4;
        songsDataGridView.Columns[2].DisplayIndex = 0;
        songsDataGridView.Columns[3].DisplayIndex = 1;
        songsDataGridView.Columns[4].DisplayIndex = 2;
    }
    
    Private Sub PopulateDataGridView()
    
        Dim row0 As String() = {"11/22/1968", "29", "Revolution 9", _
            "Beatles", "The Beatles [White Album]"}
        Dim row1 As String() = {"1960", "6", "Fools Rush In", _
            "Frank Sinatra", "Nice 'N' Easy"}
        Dim row2 As String() = {"11/11/1971", "1", "One of These Days", _
            "Pink Floyd", "Meddle"}
        Dim row3 As String() = {"1988", "7", "Where Is My Mind?", _
            "Pixies", "Surfer Rosa"}
        Dim row4 As String() = {"5/1981", "9", "Can't Find My Mind", _
            "Cramps", "Psychedelic Jungle"}
        Dim row5 As String() = {"6/10/2003", "13", _
            "Scatterbrain. (As Dead As Leaves.)", _
            "Radiohead", "Hail to the Thief"}
        Dim row6 As String() = {"6/30/1992", "3", "Dress", "P J Harvey", "Dry"}
    
        With Me.songsDataGridView.Rows
            .Add(row0)
            .Add(row1)
            .Add(row2)
            .Add(row3)
            .Add(row4)
            .Add(row5)
            .Add(row6)
        End With
    
        With Me.songsDataGridView
            .Columns(0).DisplayIndex = 3
            .Columns(1).DisplayIndex = 4
            .Columns(2).DisplayIndex = 0
            .Columns(3).DisplayIndex = 1
            .Columns(4).DisplayIndex = 2
        End With
    
    End Sub
    
  5. 借助实用工具方法,可以附加事件处理程序。

    你将处理“添加”和“删除”按钮的 Click 事件、窗体的 Load 事件和 DataGridView 控件的 CellFormatting 事件

    引发“添加”按钮的 Click 事件时,会在 DataGridView 中添加一个新的空行

    引发“删除”按钮的 Click 事件时,选定的行将被删除,除非它是新记录的行,这使用户能够添加新行。 此行始终是 DataGridView 控件中的最后一行。

    引发窗体的 Load 事件时,将调用 SetupLayoutSetupDataGridViewPopulateDataGridView 实用工具方法。

    引发 CellFormatting 事件时,Date 列中的每个单元格都会被格式化为长日期,除非无法分析单元格的值。

    public Form1()
    {
        this.Load += new EventHandler(Form1_Load);
    }
    
    private void Form1_Load(System.Object sender, System.EventArgs e)
    {
        SetupLayout();
        SetupDataGridView();
        PopulateDataGridView();
    }
    
    private void songsDataGridView_CellFormatting(object sender,
        System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
    {
        if (e != null)
        {
            if (this.songsDataGridView.Columns[e.ColumnIndex].Name == "Release Date")
            {
                if (e.Value != null)
                {
                    try
                    {
                        e.Value = DateTime.Parse(e.Value.ToString())
                            .ToLongDateString();
                        e.FormattingApplied = true;
                    }
                    catch (FormatException)
                    {
                        Console.WriteLine("{0} is not a valid date.", e.Value.ToString());
                    }
                }
            }
        }
    }
    
    private void addNewRowButton_Click(object sender, EventArgs e)
    {
        this.songsDataGridView.Rows.Add();
    }
    
    private void deleteRowButton_Click(object sender, EventArgs e)
    {
        if (this.songsDataGridView.SelectedRows.Count > 0 &&
            this.songsDataGridView.SelectedRows[0].Index !=
            this.songsDataGridView.Rows.Count - 1)
        {
            this.songsDataGridView.Rows.RemoveAt(
                this.songsDataGridView.SelectedRows[0].Index);
        }
    }
    
    Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load
    
        SetupLayout()
        SetupDataGridView()
        PopulateDataGridView()
    
    End Sub
    
    Private Sub songsDataGridView_CellFormatting(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) _
        Handles songsDataGridView.CellFormatting
    
        If e IsNot Nothing Then
    
            If Me.songsDataGridView.Columns(e.ColumnIndex).Name = _
            "Release Date" Then
                If e.Value IsNot Nothing Then
                    Try
                        e.Value = DateTime.Parse(e.Value.ToString()) _
                            .ToLongDateString()
                        e.FormattingApplied = True
                    Catch ex As FormatException
                        Console.WriteLine("{0} is not a valid date.", e.Value.ToString())
                    End Try
                End If
            End If
    
        End If
    
    End Sub
    
    Private Sub addNewRowButton_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles addNewRowButton.Click
    
        Me.songsDataGridView.Rows.Add()
    
    End Sub
    
    Private Sub deleteRowButton_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles deleteRowButton.Click
    
        If Me.songsDataGridView.SelectedRows.Count > 0 AndAlso _
            Not Me.songsDataGridView.SelectedRows(0).Index = _
            Me.songsDataGridView.Rows.Count - 1 Then
    
            Me.songsDataGridView.Rows.RemoveAt( _
                Me.songsDataGridView.SelectedRows(0).Index)
    
        End If
    
    End Sub
    

测试应用程序

现在可以测试窗体,以确保它的行为符合预期。

测试窗体

  • 按 F5 运行该应用程序。

    你将看到一个显示 PopulateDataGridView 中列出的歌曲的 DataGridView 控件。 可以使用“添加行”按钮添加新行,也可以使用“删除行”按钮删除选定的行。 未绑定的 DataGridView 控件是数据存储,其数据独立于任何外部源,例如 DataSet 或数组。

后续步骤

此应用程序让你对 DataGridView 控件的功能有了一个基本的了解。 可以通过多种方式自定义 DataGridView 控件的外观和行为:

另请参阅