XtraGrid 支持绑定列和非绑定列。 本主题介绍了非绑定列 —— 没有绑定到数据源中任何字段的网格控件列。
绑定列和非绑定列
绑定列 从网格的数据源中获取数据,数据源是由 GridControl.DataSource 和 GridControl.DataMember 属性指定的。 绑定列的 GridColumn.FieldName 属性引用了数据源中的有效字段。
非绑定列 没有被绑定到下层数据源中的任何字段。 可以使用下列两种方法之一为非绑定列提供数据:
- 通过 GridColumn.UnboundExpression 属性指定一个公式 (字符串表达式),用于为该列自动计算取值。 允许根据其他列的取值计算表达式值。 在表达式中可以使用常数、多个函数和运算符。 请参阅 表达式 来学习相关语法。
- 接管 ColumnView.CustomUnboundColumnData 事件。 在该事件中,可以实现任何复杂的自定义逻辑。
使用此事件,可以允许最终用户编辑非绑定列中的取值。 当最终用户修改单元格时,CustomUnboundColumnData 事件发生,允许保存更改。
非绑定列必须满足下列两个要求:
- 它的 GridColumn.FieldName 必须设置为一个唯一值,并且不能引用网格控件的数据源中的任何字段;
- 该列的 GridColumn.UnboundType 属性必须根据列要显示的数据类型(Boolean、DateTime、Decimal、Integer、String 或 Object),被设置为一个适当的取值。 而不应该设置为 UnboundColumnType.Bound。
非绑定列的 GridColumn.UnboundType 属性决定了它的功能如何。 首先,它决定了用于呈现列的取值的默认编辑器。 例如, 如果 GridColumn.UnboundType 属性值设置为 UnboundColumnType.DateTime,则该列将使用 DateEdit 内置编辑器。 其次,它决定了单元格取值如何被对齐,以及应用于该列的排序及验证规则,等等。
注意,也可以通过 GridColumn.ColumnEdit 属性为列指派特定的编辑器,以及通过 GridView.CustomRowCellEdit 事件为特定单元格指派编辑器。
如果 GridColumn.UnboundType 属性值设置为 UnboundColumnType.Bound,则推定该列被绑定到网格的数据源中的特定字段。 该字段由 GridColumn.FieldName 属性确定。
非绑定列的数据
可以通过 GridColumn.UnboundExpression 属性创建一个表达式、或者通过接管 ColumnView.CustomUnboundColumnData 事件来为非绑定列提供数据。 要学习关于表达式的语法,请参阅 表达式。
在运行时刻,最终用户可以通过 Expression Editor(表达式编辑器) 来编辑非绑定列的表达式。 可以通过上下文菜单 (如果 ColumnView.ShowUnboundExpressionEditor 选项被启用) 或者在代码中通过 ColumnView.ShowUnboundExpressionEditor 方法来打开“表达式编辑器”。
在默认情况下,允许在非绑定列的单元格中编辑数据。 但是也可能想要阻止最终用户编辑非绑定列。 要让列只读,则可以使用 OptionsColumn.AllowEdit 或 OptionsColumn.ReadOnly 选项。
如果需要保存由最终用户对非绑定列作出的更改,则应该通过 ColumnView.CustomUnboundColumnData 事件装载非绑定列。 此事件的 IsGetData 和 IsSetData 参数决定了事件的当前操作模式。如果 IsGetData 参数设置为 true (因而 IsSetData 参数被设置为 false),则事件处理程序应该为非绑定列提供数据。 应该根据当前被处理的行来指派 Value 参数值。 可以使用 ListSourceRowIndex 参数识别当前行,此参数指定了行在网格数据源中的索引号。 它不受任何排序或筛选设置的影响。
如果 IsSetData 参数被设置为 true (因而 IsGetData 参数被设置为 false),则该事件是由于在网格控件内修改数据而引发的。 在这种情况下, Value 参数包含了修改后的数据,应该存储它以供将来使用。
注意 |
---|
在接管 CustomUnboundColumnData 事件时,如果需要获取或设置特定单元格的取值,则使用由绑定数据源提供的方法。 事件的 ListSourceRowIndex 参数允许识别当前数据行。 在 CustomUnboundColumnData 事件中,不要使用由视图对象提供的方法 (例如 ColumnView.GetRowCellValue、ColumnView.SetRowCellValue 等) 来获取/设置单元格取值。 这些方法把 行句柄 作为参数。 但是,在视图对象还未被初始化时,CustomUnboundColumnData 事件可能会被调用。 在这种情况下,还没有适当地初始化行句柄。 调用这些方法也可能会导致递归调用该事件。 |
使用非绑定列
但是,请记住此种情形: 非绑定列从自定义数据源中取回其数据,以及把记录添加到网格的主要数据源中、或者从网格的主要数据源中删除记录。 当添加记录时,通常需要把新条目添加到与网格中新记录对应的自定义数据源中。 类似地,当删除记录时,通常需要在自定义数据源中删除相应的条目。 要接收记录已经被添加或删除的通知,则使用由数据源提供的方法。
当 打印 或 导出 网格控件时,非绑定列的内容也会被打印/导出。
注意,XtraGrid 不能只使用非绑定列工作 (没有通过 GridControl.DataSource 和 GridControl.DataMember 属性把控件绑定到数据源)。
自定义显示文本
当打印/导出网格时,通过 ColumnView.CustomColumnDisplayText 事件提供的自定义显示文本将被打印/导出。 而决不会打印/导出通过自定义绘制事件提供的自定义显示文本。
由 GridView.CustomDrawCell (CardView.CustomDrawCardFieldValue) 事件提供文本的列,不能根据所提供的显示文本进行排序。 它们始终通过编辑值进行排序。 在对这种列进行排序时,如果特定的编辑值匹配,则根据数据源中的行顺序号来排列行。对于没有通过 ColumnView.CustomUnboundColumnData 事件装载的非绑定列,分组和筛选功能是不可用的。 在对这种列进行排序时,根据数据源中的行顺序号来排列行。
示例 —— 通过事件实现非绑定列
假设 XtraGrid 被绑定到 NWind 数据库中的 [Order Details] 表。 网格控件包含了“Quantity”、“UnitPrice”和“Discount"”列,这些列被绑定到数据库表中的相应字段。 下面的示例展示了如何把一个非绑定列添加到网格控件中,根据表达式 Quantity*UnitPrice*(1-Discount) 来显示每张订单的合计。
如果显示如下:
另一个演示了使用非绑定列的示例,请参阅 非绑定列 指南。
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Views.Base; using DevExpress.XtraGrid.Columns; private void Form1_Load(object sender, System.EventArgs e) { // ... gridControl1.ForceInitialize(); // Create an unbound column. GridColumn unbColumn = gridView1.Columns.AddField("Total"); unbColumn.VisibleIndex = gridView1.Columns.Count; unbColumn.UnboundType = DevExpress.Data.UnboundColumnType.Decimal; // Disable editing. unbColumn.OptionsColumn.AllowEdit = false; // Specify format settings. unbColumn.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric; unbColumn.DisplayFormat.FormatString = "c"; // Customize the appearance settings. unbColumn.AppearanceCell.BackColor = Color.LemonChiffon; } // Returns the total amount for a specific row. decimal getTotalValue(ColumnView view, int listSourceRowIndex) { DataRow row = nwindDataSet.Tables["Order Details"].Rows[listSourceRowIndex]; decimal unitPrice = Convert.ToDecimal(row["UnitPrice"]); decimal quantity = Convert.ToDecimal(row["Quantity"]); decimal discount = Convert.ToDecimal(row["Discount"]); return unitPrice * quantity * (1 - discount); } // Provides data for the Total column. private void gridView1_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e) { if (e.Column.FieldName == "Total" && e.IsGetData) e.Value = getTotalValue(sender as ColumnView, e.ListSourceRowIndex); } |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Views.Base Imports DevExpress.XtraGrid.Columns Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' ... gridControl1.ForceInitialize() ' Create an unbound column. Dim unbColumn As GridColumn = GridView1.Columns.AddField("Total") unbColumn.VisibleIndex = GridView1.Columns.Count unbColumn.UnboundType = DevExpress.Data.UnboundColumnType.Decimal ' Disable editing. unbColumn.OptionsColumn.AllowEdit = False ' Specify format settings. unbColumn.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric unbColumn.DisplayFormat.FormatString = "c" ' Customize the appearance settings. unbColumn.AppearanceCell.BackColor = Color.LemonChiffon End Sub ' Returns the total amount for a specific row. Private Function getTotalValue(ByVal view As ColumnView, _ ByVal listSourceRowIndex As Integer) As Decimal Dim row As DataRow = NwindDataSet.Tables("Order Details").Rows(listSourceRowIndex) Dim unitPrice As Decimal = Convert.ToDecimal(row("UnitPrice")) Dim quantity As Decimal = Convert.ToDecimal(row("Quantity")) Dim discount As Decimal = Convert.ToDecimal(row("Discount")) Return unitPrice * quantity * (1 - discount) End Function ' Provides data for the Total column. Private Sub GridView1_CustomUnboundColumnData(ByVal sender As Object, _ ByVal e As CustomColumnDataEventArgs) Handles GridView1.CustomUnboundColumnData If e.Column.FieldName = "Total" And e.IsGetData Then e.Value = _ getTotalValue(CType(sender, ColumnView), e.ListSourceRowIndex) End Sub |
示例 —— 使用表达式实现非绑定列
下列代码展示了如何使用 表达式 创建一个非绑定列 (Ext Price) 并装载数据。 根据公式计算该列的数据: [Quantity] * [UnitPrice] * (1 - [Discount]),此公式是通过 GridColumn.UnboundExpression 属性设置的。
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Columns; GridColumn columnExtPrice = new GridColumn(); columnExtPrice.FieldName = "ExtPrice"; columnExtPrice.Caption = "Ext Price"; columnExtPrice.UnboundType = DevExpress.Data.UnboundColumnType.Decimal; columnExtPrice.UnboundExpression = "[Quantity] * [UnitPrice] * (1 - [Discount])"; gridView1.Columns.Add(columnExtPrice); columnExtPrice.VisibleIndex = 0; |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Columns Dim columnExtPrice As GridColumn = New GridColumn() columnExtPrice.FieldName = "ExtPrice" columnExtPrice.Caption = "Ext Price" columnExtPrice.UnboundType = DevExpress.Data.UnboundColumnType.Decimal columnExtPrice.UnboundExpression = "[Quantity] * [UnitPrice] * (1 - [Discount])" GridView1.Columns.Add(columnExtPrice) columnExtPrice.VisibleIndex = 0 |