65.9K
CodeProject 正在变化。 阅读更多。
Home

DataGridViewExtension

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (30投票s)

2011 年 5 月 12 日

CPOL

7分钟阅读

viewsIcon

114944

downloadIcon

14456

DataGridView 控件的扩展,其中包含我通常手动添加的功能,但现在封装在一个类中。

引言

这个项目是我多年来在 DataGridView 中实现的所有零散功能,并将其组合成一个扩展的 DataGridView 类。附加功能包括行上的子窗体,使 ENTER 键按下时向右移动,CTRL + ' 将从上方单元格复制内容,无需设置交替行单元格样式即可实现交替行颜色,自动完成文本框列,DateTimePicker 列和时间列。

背景

引言中列出的功能是我通常必须编程到我使用的每个单独的 DataGridView 控件中的功能。不可避免地,我会在某些网格中遗漏功能,最终用户会抱怨。当我将所有这些功能封装在一个可以从设计器中使用的单个类中时,我的生活变得更轻松了。

详细功能

子窗体

此项目中的子窗体设计得与 MS Access 中的子窗体非常相似,但增加了一些额外功能。您可以使用子窗体执行以下操作:

  • 根据行的数据绑定项显示不同的子窗体
  • 根据行的数据绑定项指定不同类型的数据发送到子窗体
  • 在一行上显示多个不同类型的子窗体
  • 当水平滚动 DataGridViewExtension 时,保持子窗体静止或可移动
  • 显示一个包含另一个 DataGridViewExtension 的子窗体,这样您就可以在 DataGridViewExtension 中无限深入地进行钻取

Enter 键向右移动

此功能可在设计器中选择,但如果启用,则当用户按下 Enter 键时,焦点会移到右侧的单元格(或下一行的第一个单元格),而不是正下方。如果用户从自动完成列表框中单击一个选项,此功能也会将焦点向右移动。

交替行颜色

此功能默认启用,交替颜色为浅灰色。颜色以及启用/禁用此功能均可在设计器中编辑。

从上方单元格复制内容

与 MS Access 一样,如果您按下 CRTL + ',则正上方单元格的内容将粘贴到当前单元格中。此功能始终启用。

AutoCompleteTextBoxColumn

DataGridViewExtension 添加此列将允许您直接从设计器中选择单元格所需的自动完成类型。不再需要实现 EditingControlShowing 事件以使您的单元格具有自动完成功能。

DateTimePickerColumn

这会将日期时间选择器显示为此列中单元格的编辑控件。FormatShowUpDown 可在设计器中选择。

时间列

此列将文本框显示为编辑控件,但其值为 DateTime。在此单元格中输入时间可以通过输入 24 小时制时间、带或不带冒号、带或不带 AM/PM,或者您可以使用 'p' 表示 PM。您可以只输入小时和分钟,或小时、分钟和秒。时间格式可在设计器中编辑。

例如:1600、400PM、400 PM、400p、400 p、4:00 PM、16:00、4:00p、4:00pm 都是输入 4:00 PM 的有效方式。

081530、81530、8:15:30a、8:15:30 AM、81530a、081530 AM、81540am 都是输入 8:15:30 AM 的有效方式

Using the Code

子窗体

您需要做的第一件事是创建一个继承 Extensions.DataGridViewSubForm 类的类。只有继承此基类的类才能设置为 DataGridViewExtension 的子窗体。在您创建的类中,确保您具有接受 objectExtensions.DataGridViewSubformCell 并将这些变量传递给基类的构造函数。DataGridViewExtension 将始终使用此构造函数创建您的子窗体的新实例。示例如下所示。

public partial class ShiftSubForm : Extensions.DataGridViewSubForm
{
    public ShiftSubForm(object DataBoundItem, 
                        Extensions.DataGridViewSubformCell Cell)
           : base(DataBoundItem, Cell)
    {
        InitializeComponent();
    }

    private void ShiftSubForm_Load(object sender, EventArgs e)
    {
        employeeBindingSource.DataSource = 
         new List<SqlClasses.Data.CharterOperations.Employee>(
            new SqlClasses.Data.CharterOperations.Employee[] {
                (SqlClasses.Data.CharterOperations.Employee)this.DataBoundItem
            });
        employeeBindingSource.MoveFirst();
    }
}

DataGridViewSubform 只是 UserControl 类的扩展,因此您可以在设计器中非常轻松地编辑子窗体。在上面的示例中,我在设计器中包含了一个绑定源。当窗体加载时,它会将 DataBoundItem 转换为 Employee 列表,并将其设置为绑定源的数据源。

设计好子窗体后,您可以将 DataGridViewSubformColumn 添加到 DataGridViewExtension。您需要在代码中的某个位置手动设置列的子窗体类型,例如

SubFormColumn.Subform = typeof(Controls.ShiftSubForm);

您还需要为列设置 SubformDataMember 属性。这可以在设计器中完成。如果您想传递 OwningRow 的数据绑定项,只需将此字段保留为 'this'。您还可以选择数据绑定项的成员或成员的成员。例如,如果我有一个 Shift 并且我想传递 Employee 的出生日期,那么 SubformDataMember 可以是 _Employee.DOB_,但如果我想传递整个 Employee,那么 SubformDataMember 将只是 _Employee_。

DataGridViewSubformColumn 的另一个选项是 IgnoreSubformDataBindingError 字段。如果此字段设置为 True,则在尝试从 OwningRow 的数据绑定项中检索 SubformDataMember 时发生的任何错误都将被忽略,并且 null 将发送到子窗体。我建议您在调试时将其保留为 False。这样可以更容易地发现您可能犯的任何错误。但对于发布版本,请将其设置为 True,尤其是当您使用成员的成员方法时。

一行中的多个子窗体

DataGridViewExtension 中包含多个 DataGridViewSubformColumn 是完全可以的。最后显示的子窗体将放置在顶部。这是 DataGridViewExtension 中多个子窗体的结果

子窗体事件

DataGridViewSubformColumn 包含两个非常方便的事件。它们是 SubformShowingSubformClosing 事件。这两个事件都必须在代码中的某个位置手动编程。在这两个事件中,您可以选择取消子窗体的显示或关闭。在 SubformShowing 事件期间,您可以将 DataGridViewExtension 设置为显示不同的窗体,并指定不同的数据绑定项以代替默认的 SubformDataMember。下面显示了如何使用 SubformShowing 事件的示例。

void SubFormColumn_SubformShowing(Extensions.DataGridViewSubformCell sender, 
                   Extensions.SubformShowingEventArgs e)
{
    if (DoNotShowSubForms)
    {
        e.Cancel = true;
        return;
    }
    if (((Employee)e.DataBoundItem).Users.Count > 0)
    {
        e.AlternateForm = typeof(Controls.ShiftSubForm2);
        e.DataBoundItem = ((Employee)e.DataBoundItem).Users.First();
    }
}

如果您需要检查子窗体中包含的数据的有效性,SubformClosing 事件会很有用。例如

void SubFormColumn_SubformClosing(Extensions.DataGridViewSubformCell sender, 
                   Extensions.SubformClosingEventArgs e)
{
    if (!((Employee)e.Form.DataBoundItem).IsValid())
    {
        e.Cancel = true;
        MessageBox.Show("The employee details are not correct.")
    }
}

水平滚动子窗体

默认情况下,当您在 DataGridViewExtension 中左右滚动时,子窗体保持静止。如果您希望子窗体也滚动,那么您需要在代码中或在设计器中将 DataGridViewExtensionSubformsScrollHorizontally 属性设置为 true

Enter 键向右移动

此功能默认启用,但要关闭它,您只需在设计器或代码中将 EnterMovesRight 属性设置为 false

交替行颜色

您可以在设计器中或在代码中实现此功能。它默认启用。

AutoCompleteTexBox 列

将这些列之一添加到 DataGridViewExtension 会在单元格上启用自动完成。如果您使用的是自定义源,您可以在“编辑列”控件中指定选项,或在代码中以编程方式指定。下面显示了如何在代码中执行此操作的示例。

Extensions.DataGridViewAutoCompleteTextboxColumn col =
    (Extensions.DataGridViewAutoCompleteTextboxColumn)
     dataGridViewExtension1.Columns[0];
col.AutoCompleteCollection.AddRange(new string[] {
                "Test 1", "Test 2", "Test 3"
            });
for (int i = 0; i < 10; i++)
    col.AutoCompleteCollection.Add(i.ToString());

DateTimePicker 列

DataGridViewExtension 中使用这种类型的列将使 DateTimePicker 成为单元格的编辑控件。您只需在设计器中设置的属性是控件的格式、是否显示上下按钮而不是日历,以及如果您选择此格式的自定义格式。

时间列

要在您的项目中使用此列,您唯一需要设置的属性是格式。您只能为此列使用时间格式字符串(即:h、H、m、s、t、hh、HH、mm、ss、tt 和 :)。

历史

  • 2011 年 5 月 11 日 - 发布原始版本。
  • 2011 年 5 月 17 日 - 修复了定位错误并添加了演示项目。
  • 2011 年 5 月 20 日 - 修复了一个错误,即如果所属行的 DataBoundItem 实现 INotifyPropertyChanged 并且此 DataBoundItem 正在子窗体中编辑,则子窗体将被移除。
© . All rights reserved.