ASPxGridView:无法有选择地隐藏自定义命令按钮。这是我这边的错误吗?

ASPxGridView: Cannot hide custom command button selectively. Is it a bug on my side?

总结:当试图在ASPxGridView命令列中隐藏自定义命令按钮时,它奇怪地隐藏了按钮,其中一个按钮文本出现在过滤器行中输入,按钮处理程序停止工作。出现 "More controls with the DXCBtn_0_9_-1 were found. The FindControl requires unique identifiers of the controls"(松散翻译)之类的错误消息。

我正在使用 DevExpress 14.2.3.0,网格视图嵌套在另一个网格视图和 ASPxRoundPanels 中。

详细信息:命令栏包含以下自定义按钮...

    <dx:GridViewCommandColumn VisibleIndex="9">
        <CustomButtons>
            <dx:GridViewCommandColumnCustomButton ID="btnClose" Text="Close as done">
            </dx:GridViewCommandColumnCustomButton>
            <dx:GridViewCommandColumnCustomButton ID="btnReopen" Text="Reopen">
            </dx:GridViewCommandColumnCustomButton>
        </CustomButtons>
    </dx:GridViewCommandColumn>

按钮显示良好(作为链接)并且以下代码可以很好地处理它们:

protected void gvMilestoneTasks_CustomButtonCallback(object sender, ASPxGridViewCustomButtonCallbackEventArgs e)
{
    ASPxGridView grid = sender as ASPxGridView;
    if (e.ButtonID == "btnClose")
    {
        int milestoneID = Convert.ToInt32(grid.GetRowValues(e.VisibleIndex, "ID"));
        DbUtil.ExecuteNonQuery(String.Format("EXEC sp_milestone_tasks_close_open {0}, 0, N'{1}'", 
                                        milestoneID, Page.User.Identity.Name));
        grid.DataBind();
    } else if (e.ButtonID == "btnReopen")
    {
        int milestoneID = Convert.ToInt32(grid.GetRowValues(e.VisibleIndex, "ID"));
        DbUtil.ExecuteNonQuery(String.Format("EXEC sp_milestone_tasks_close_open {0}, 1, N'{1}'",
                                        milestoneID, Page.User.Identity.Name));
        grid.DataBind();
    }
}

(即调用具有不同参数的专用 SQL 存储过程 [如果好奇请注意第二个参数],并且 grid.DataBind(); 用于刷新状态列的内容。)

我只想显示其中一个按钮。当该行显示打开的那一行时,应该只显示并激活关闭按钮。当该行显示它之前已关闭时,只有“重新打开”按钮应该可见且处于活动状态。

我尝试在 CustomButtonInitialize 事件处理程序中处理可见性(基于状态信息——当 closed 在数据库中为 NULL 时,它是打开的;否则,closed 包含关闭时间的日期时间):

protected void gvMilestoneTasks_CustomButtonInitialize(object sender, ASPxGridViewCustomButtonEventArgs e)
{
    if (e.VisibleIndex == -1)
        return;

    ASPxGridView grid = sender as ASPxGridView;
    if (e.ButtonID == "btnClose")
    {
        object o = grid.GetRowValues(e.VisibleIndex, "closed");
        bool flagVisible = Convert.IsDBNull(o);
        e.Visible = flagVisible ? DefaultBoolean.True : DefaultBoolean.False;
    }
    else if (e.ButtonID == "btnReopen")
    {
        object o = grid.GetRowValues(e.VisibleIndex, "closed");
        bool flagVisible = !Convert.IsDBNull(o);
        e.Visible = flagVisible ? DefaultBoolean.True : DefaultBoolean.False;
    }
}

我还可以观察到浏览器中的错误消息 "More controls with the DXCBtn_0_9_-1 were found. The FindControl requires unique identifiers of the controls"(粗略翻译)——这隐藏在控件的深处;我没有使用 FindControl.

bug隐藏在哪里?

感谢您的帮助。

我认为这是 2014 2.5 版中修复的 DevExpress 错误:

Fix

原因是 FilterRow 表现为显示网格的另一行。它被认为是另一个可见的行。这样,在单元格类型被检测为过滤器的情况下,处理程序也应该 return 尽早。

if (e.VisibleIndex == -1 || e.CellType == GridViewTableCommandCellType.Filter)
    return;

或者,该部分可以更改为...

if (e.CommandCellType != GridViewTableCommandCellType.Data)
    return;