DevExpress Gridview 禁用和着色单元格

DevExpress Gridview Disabling & Coloring Cells

我正在使用 DevExpress Gridview 控件。

我有两个不同的问题:

我有四行数据(始终是数据集中的前 4 条记录),某些单元格始终不得编辑。这些行的某些列应具有灰色背景,表明它们已被禁用。

现在,我唯一能用的是GridView2_RowCellStyle:

Dim View As GridView = sender

If e.Column.FieldName = "Percent" Or e.Column.FieldName = "PGPct" Or e.Column.FieldName = "VGPct" Then
    If e.RowHandle = 0 Or e.RowHandle = 1 Or e.RowHandle = 2 Or e.RowHandle = 3 Then
        e.Appearance.BackColor = Color.Silver
    End If
End If

GridView2_ShowingEditor:

If GridView2.FocusedColumn.FieldName.ToString = "Percent" Or GridView2.FocusedColumn.FieldName.ToString = "PGPct" Or GridView2.FocusedColumn.FieldName.ToString = "VGPct" Then
    If GridView2.FocusedRowHandle = 0 Then
        e.Cancel = True
    End If
End If

但是,当用户对数据进行排序或分组时,这些行可能会发生变化,这使得无法通过 FocusedRowHandle 或 RowHandle 选择它们。

如何确保这些单元格始终处于禁用状态且背景为灰色,即使在排序或分组时也是如此?

我认为您可以做一些事情来完成这项工作。

  1. 向绑定的域对象添加一个 属性(并因此添加一列)并将其命名为 RowNumber
  2. 填充数据后,按顺序为 RowNumber 编号,以便对象本身跟踪它所在的行。更好的是,使用静态变量使其成为对象的一部分,以便它自动递增
  3. 您现在可以直接使用网格设计器中的格式条件,而不是使用 RowCellStyle——这是一种无需代码的方式来完成同样的事情
  4. 就锁定行而言,如果您使用的是绑定源,请使用 CurrentChanged 事件有选择地使这些列对某些行只读。实际上,您是根据选择的行切换列的只读 属性,这将阻止编辑某些行

我相信,如果您不清楚其中任何一个,您可以告诉我,而不是深入讨论这些令人痛苦的细节。我是 C# 专家,但我很确定 C# 上的模拟示例足够清晰,您可以将其转换为 VB.net.

-- 编辑 2015 年 12 月 15 日 --

关于第 1 项,假设您的绑定对象是一个域 Object/POCO/whatever,如果您添加一个 属性:

private int _RowNum;
public int RowNum
{
    get { return _RowNum; }
}

并确保在收集数据时分配值或让构造函数执行此操作:

private static _Serial = 1;

public MyDomainObject()
{
    _RowNum = _Serial++;
}

或者——如果你想事后做:

int serial = 1;
MyDomainObjectList.Foreach(x => x.RowNum = serial++);

对于第 4 项,我假设您有一个绑定源,如果您在绑定源上触发 CurrentChanged 事件:

bindingSource1.CurrentChanged += new System.EventHandler(bindingSource1_CurrentChanged);

它可能看起来像这样:

private void bindingSource1_CurrentChanged(object sender, EventArgs e)
{
    MyDomainObject curr = (MyDomainObject)bindingSource1.Current;
    bool locked = curr.RowNum >= 1 && curr.RowNum <= 4;

    colPercent.OptionsColumn.ReadOnly =
        colPGPct.OptionsColumn.ReadOnly = locked;
}

这与格式化没有任何关系(由我的建议 #3 处理),但它会根据选择的行有选择地锁定或解锁列。由于用户无法编辑他不在的行,这将实现您使某些行不可编辑的目标。

我为 C# 道歉。我知道你问了一个 VB 问题,但我认为你阅读我的 C# 比让我猜测 VB 语法是什么样子更容易。

看看这是否更有意义,或者我是否可以进一步澄清。这是一个很难推测的问题,所以我知道这是否是一个失败的原因。

您可以使用GridView.GetDataSourceRowIndex方法获取您的基础数据源的实际索引。该索引不依赖于 GridView 中的排序、分组、过滤等,并且始终 return 同一行的相同值。
例如:

Private Sub gridView2_RowCellStyle(ByVal sender As Object, ByVal e As RowCellStyleEventArgs) Handles gridView2.RowCellStyle
    Dim View As GridView = sender

    If e.Column.FieldName = "Percent" Or e.Column.FieldName = "PGPct" Or e.Column.FieldName = "VGPct" Then
        If View.GetDataSourceRowIndex(e.RowHandle) < 4 Then
            Dim colors = CommonSkins.GetSkin(UserLookAndFeel.Default).Colors
            Dim textColor = colors.GetColor(CommonColors.DisabledText)
            Dim backColor = colors.GetColor(CommonColors.DisabledControl)

            e.Appearance.ForeColor = textColor
            e.Appearance.BackColor = backColor
        End If
    End If
End Sub