C# winform dev gridcontrol 非绑定列,unbound的使用

背景

  需要在gridview中增加一列。之前的数据都是通过Datatable 绑定到GridControl.DataSource呈现。(GridControl 不能只通过非绑定列呈现)

  Note that the Grid Control cannot operate with only unbound columns (without binding the control to a data source using the GridControl.DataSource and GridControl.DataMember properties)。

问题描述

  在gridview中通道Columns.AddField()添加了一列(GridColumn),当对这一列的单元格进行赋值时无效果。

  赋值方式是通过gridView1.SetRowCellValue();

解决方法

  响应gridView的CustomUnboundColumnData 消息,其中CustomColumnDataEventArgs 包含以下属性 IsSetData,IsGetData,Value等。

  此消息在gridview初始化,以及其它绑定列的数据被修改时被激活,此时IsGetData为true,IsSetData为false;

  对非绑定列的单元格进行编辑(添加非绑定列以后默认是可编辑的)和对非绑定列进行SetRowCellValue()时消息也被激活,此时IsSetData为true,IsGetData为false;

  在IsSetData为true的时候,改变Value的值对单元格内呈现的值无效,该值不会被显示到界面上。所以SetRowCellValue方法无法对非绑定列的单元格进行赋值。

  当IsGetData为true的时候,改变Value的值单元格内的值也就改变了。

  通常的,在CustomUnboundColumnData 消息被响应的时候如果IsSetData 为true,该消息会被再次响应,此时IsGetData为true;

  所以要使非绑定列的编辑和SetRowCellValue()有效,代码如下:

    
//以下代码只适用于单行,因为数据只暂存在一个edit对象,当有多行的时候,每一行的数据都有可能变成edit
object edit; private void gridView1_CustomUnboundColumnData(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e) { if(e.IsSetData) { edit = e.Value; }else if(e.IsGetData) { e.Value = edit; } }

问题查找过程

  当遇到SetRowCellValue()无效的时候,我首先想到的是属性是否设置正确。

  首先,非绑定列被创建时,visible 属性为false。由此可见,非绑定列与绑定列相比,有很多属性都是需要手动设置的。

  依据以往的了解,决定单元格数据显示的有三个属性:

  ColumnType,列的类型

  DisplayFormat.FormatType ,格式类型

  DisplayFormat.FormatString,格式字符串

  后面两个属性在使用绑定列的时候我通常也会设置,所以已经设置好。

  于是设置ColumnType,但是该属性为只读类型,看来只适用于绑定列。

  通过type关键字提示发现,存在UnboundType,默认情况下该值为None.于是设置为DevExpress.Data.UnboundColumnType.Decimal;

  结果依然失败。

  Google后发现

  需要响应gridView的CustomUnboundColumnData 消息

总结

  由于非绑定列在处理数据输入时比较麻烦:消息响应两次,需要新建数据对象进行存储,删除时也需要删除对应数据源。所以不适合作为编辑列。

  However, please keep in mind those situations in which unbound columns retrieve their data from a custom data source, and a record is added to or deleted from the grid's main data source. When a record is added, you usually need to add a new entry to the custom data source that corresponds to the new record in the grid. Similarly, when a record is deleted you usually need to delete the corresponding entry in the custom data source. To receive notifications about a record that has been added or removed, use the methods provided by the data source.

猜测

  官方设计的非绑定列运用场景主要适用以下示例场景:

  官方示例代码:

using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
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(GridView view, int listSourceRowIndex) {
    decimal unitPrice = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "UnitPrice"));
    decimal quantity = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "Quantity"));
    decimal discount = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "Discount"));
    return unitPrice * quantity * (1 - discount);
}

// Provides data for the Total column.
private void gridView1_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e) {
   GridView view = sender as GridView;
   if (e.Column.FieldName == "Total" && e.IsGetData) e.Value = 
     getTotalValue(view, e.ListSourceRowIndex);
}

  

  

  

参考资料:

官方文档:

https://documentation.devexpress.com/#WindowsForms/CustomDocument1477

同一问题:

https://stackoverflow.com/questions/20137808/how-to-set-a-value-to-unbound-column-cell-setrowcellvalue-grinview-winforms