在本教程中,您将学习如何将DevExpress WinForms的网格控件绑定到实体框架数据源、如何使用数据注释属性来更改网格显示和管理数据的方式,以及如何将单元格值更改发送回数据源。
P.S:DevExpress WinForms拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!
获取DevExpress WinForms v24.1正式版下载(Q技术交流:749942875)
起点
从一个项目开始,它有一个Windows Form和一个空的GridControl,该解决方案还包括一个默认名为Model1的实体框架模型,您可以双击它来查看图表上的可视化表示。在本教程中,使用修改版本的AdventureWorks数据库,它只包含一个表,其中只有几个字段。
绑定到实体框架数据源
将实体框架模型绑定到网格控件的最简单方法是使用数据源配置向导,调用DevExpress WinForms网格控件的智能标记并单击数据源向导。
选择Entity Framework技术并选择现有的数据连接或创建一个新的数据连接,在本教程中使用到样例Microsoft AdventureWorksDW2008R2数据库的现有连接,单击Next继续。
在下一页,您将被要求选择所需的绑定模式。选择Binding using Binding Source组件选项,然后单击Next。
最后,选择要在网格控件中显示的表格。
绑定到实体框架数据的结果
网格控件现在绑定到EF数据,并且已经生成了所有必需的代码,您可以在.cs文件中看到自动生成的代码。现在运行应用程序来查看结果。
下面是一些关于grid如何显示其绑定数据的观察。
- 简单的数字格式应用于Price字段,但使用Currency格式会更有意义。
- Description字段包含很长的值,因此很难在网格单元格中编辑它们。
- 网格足够智能,可以为绑定到日期-时间字段的列分配一个特殊的编辑器。
- 列名只是从字段名派生而来。
- 显然没有应用于网格的数据验证规则。
应用数据标注属性
所有这些默认操作都可以使用DevExpress WinForms GridControl设置进行更改,另一种方法是更改数据字段属性或数据注释属性。当您有多个控件绑定到同一数据源时,这可能会派上用场。这样您就不必设置相同的规则,看看这是怎么回事。
打开包含表格数据模型的DimProducts.cs文件,在这里您可以看到所有可用的数据字段,它们被声明为DimProduct类的属性。
C#
public partial class DimProduct {
public int ProductKey { get; set; }
public string EnglishProductName { get; set; }
public Nullable<decimal> DealerPrice { get; set; }
public string EnglishDescription { get; set; }
public Nullable<System.DateTime> StartDate { get; set; }
public Nullable<System.DateTime> EndDate { get; set; }
}
VB.NET
Partial Public Class DimProduct
Public Property ProductKey() As Integer
Public Property EnglishProductName() As String
Public Property DealerPrice() As Decimal?
Public Property EnglishDescription() As String
Public Property StartDate() As Date?
Public Property EndDate() As Date?
End Class
向这些属性添加数据属性,看看这会如何改变网格操作。
注意:应用程序应该引用System.ComponentModel.DataAnnotations库来完成此操作。
- 对于EnglishProductName字段,添加Required属性,这将不允许最终用户为该列的单元格设置空值。
C#
[Required]
public string EnglishProductName { get; set; }
VB.NET
<Required>
Public Property EnglishProductName() As String
运行应用程序来确保不再允许空值。
对于DealerPrice字段,添加DataType属性,以指示应该将这些整数值视为货币数据。此外,应用Range属性来设置允许的最小值和最大值。
C#
[DataType(DataType.Currency), Range(200, 5000)]
public Nullable<decimal> DealerPrice { get; set; }
VB.NET
<DataType(DataType.Currency), Range(200, 5000)>
Public Property DealerPrice() As Decimal?
- 对于EnglishDescription字段,使用DataType属性将数据类型从简单文本更改为多行文本,Display属性将指定列的Name和Description。
C#
[DataType(DataType.MultilineText), Display(Name = "Description", Description = "Detailed product description")]
public string EnglishDescription { get; set; }
VB.NET
<DataType(DataType.MultilineText), Display(Name := "Description", Description := "Detailed product description")>
Public Property EnglishDescription() As String
运行应用程序来查看用于列标头及其工具提示的更新标题,另外注意单元格现在使用MemoEdit,因为您将数据类型指定为多行文本。
- 最后对于StartDate和EndDate列,应用不同的格式化和编辑规则。第一个日期将被视为一个简单的文本值,第二列的数据仍然是日期-时间对象,但格式将更改为显示完整的月份、姓名和年份。
C#
[DataType(DataType.Text)] public Nullable<System.DateTime> StartDate { get; set; } [DisplayFormat(DataFormatString = "MMMM/yyyy")] public Nullable<System.DateTime> EndDate { get; set; }
VB.NET
<DataType(DataType.Text)>
Public Property StartDate() As Date?
<DisplayFormat(DataFormatString := "MMMM/yyyy")>
Public Property EndDate() As Date?
启动应用程序,看到StartDate列中没有显示任何特殊的编辑器。EndDate列保留了编辑器,但格式发生了变化。
将数据发回数据源
要确保网格控件中的单元格值更改被发送回数据源,您需要添加几行代码。当网格引发ColumnView.RowUpdated事件时保存更改,您需要访问数据源上下文,因此必须更改变量的作用域,使其对Form类中的所有方法都可用。在处理程序中,需要做的就是调用SaveChanges方法。
C#
DXApplication.AdventureWorksDW2008R2Entities dbContext;private void gridView1_RowUpdated(object sender, DevExpress.XtraGrid.Views.Base.RowObjectEventArgs e) {
dbContext.SaveChanges();
}
VB.NET
Private dbContext As DXApplication.AdventureWorksDW2008R2EntitiesPrivate Sub gridView1_RowUpdated(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.RowObjectEventArgs)
dbContext.SaveChanges()
End Sub
现在运行应用程序并更改Dealer Price列中的值,将焦点移动到另一行,来确保引发ColumnView.RowUpdated事件。然后关闭应用程序并再次运行它,您将看到该值已保存。