【问题标题】:Column 'ID' does not belong to table DefaultView列“ID”不属于表 DefaultView
【发布时间】:2016-08-09 09:40:32
【问题描述】:

我有一个带有 DataKey“ID”的 Gridview“Gridview_ActionPlan”和一个根据数据源的值为某些单元格着色的 RowDataBound 事件。直到这里一切都很好。现在我添加了一个命令来根据条件为一列提供可见性,它会抛出错误“列'ID'不属于表 DefaultView”

if (e.Row.Cells[3].Text != "1" && e.Row.Cells[2].Text != "2")
{
    Gridview_ActionPlan.Columns[5].Visible = true;
    LinkButton LB2 = e.Row.Cells[5].FindControl("ButtonOpen") as LinkButton;
    LB2.Visible = true;
}

...和列[5]

        <asp:templatefield ItemStyle-HorizontalAlign="center" Visible="false">
            <ItemTemplate>
                <asp:LinkButton ID="ButtonOpen" runat="server" CommandArgument = '<%# Eval("ID") %>' OnClick="OpenNode" style="vertical-align:text-bottom;text-decoration:none" Visible="false">
                    <asp:Image runat="server" src="img/plus_.png" id="OpenNodeIMG" border="0" Visible="true"/>
                </asp:LinkButton>
            </ItemTemplate>
        </asp:templatefield>

现在,如果我为该列提供静态可见性并删除“Gridview_ActionPlan.Columns[5].Visible = true;”然后不会引发错误。这对我来说没有意义

马丁

这是完整的 OnRowDataBound 事件: 注释:SQLConnection 部分根据所选语言使用正确的标题填充网格。这有点费时间,所以如果有人有更好的主意,请随意......虽然这不是那个帖子的问题

protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    var gv = (GridView)sender;
    string GridID = Convert.ToString(gv.ID);

    SqlConnection objConn = new SqlConnection("Data Source=XXXXXX");
    SqlDataAdapter adapter = new SqlDataAdapter();
    SqlCommand objCommand = new SqlCommand(@"select Text
                                             from EPC_Menu
                                             where language = @language and MenuControlID = @GridID
                                             order by MenuID", objConn);
    objCommand.Parameters.Add("@GridID", SqlDbType.NVarChar).Value = GridID;
    objCommand.Parameters.Add("@language", SqlDbType.NVarChar).Value = LanguageLabel.Text;
    DataSet t = new DataSet();
    adapter.SelectCommand = objCommand;
    objConn.Open();
    adapter.Fill(t);
    objConn.Close();

    if (e.Row.RowType == DataControlRowType.Header)
    {
        for(int i = 0; i+6 < gv.Columns.Count; i++)
        {
            if (t.Tables[0].Rows.Count > 0)
            {
                e.Row.Cells[i+6].Text = t.Tables[0].Rows[i][0].ToString();
            }
        }
    }
    else
    {
        if (e.Row.Cells[1].Text == "True")
        {
            e.Row.Cells[9].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
            e.Row.Cells[10].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
        }
        else if (e.Row.Cells[2].Text == "2")
        {
            e.Row.BackColor = System.Drawing.ColorTranslator.FromHtml("#CCECF4");
        }
        if (e.Row.Cells[3].Text != "1" && e.Row.Cells[2].Text != "2" && !string.IsNullOrEmpty(e.Row.Cells[3].Text) && e.Row.RowType == DataControlRowType.DataRow && Gridview_ActionPlan.EditIndex != e.Row.RowIndex)
        {
            LinkButton LB2 = e.Row.Cells[5].FindControl("ButtonOpen") as LinkButton;
            LB2.Visible = true;
        }
    }
}

这里已经发布了第 0 - 5 列的网格视图:

<asp:GridView ID="Gridview_ActionPlan" runat="server" 
    DataSourceID="ActionPlan" 
    DataKeyNames="ID" 
    AutoGenerateColumns="false" 
    Font-Names="Arial" 
    OnRowDataBound="OnRowDataBound">
    <RowStyle BorderColor="White" 
        Font-Size="12px" VerticalAlign="Bottom" />
    <Columns>
        <asp:BoundField DataField="ID" 
            ItemStyle-CssClass="hiddencol" 
            HeaderStyle-CssClass="hiddencol" />
        <asp:BoundField DataField="CustomerRequired" 
            ItemStyle-CssClass="hiddencol" 
            HeaderStyle-CssClass="hiddencol" />
        <asp:BoundField DataField="Type" 
            ItemStyle-CssClass="hiddencol" 
            HeaderStyle-CssClass="hiddencol" />
        <asp:BoundField DataField="CNT" 
            ItemStyle-CssClass="hiddencol" 
            HeaderStyle-CssClass="hiddencol" />
        <asp:TemplateField ItemStyle-HorizontalAlign="left" 
            ItemStyle-Width="50px" Visible="false">
            <ItemTemplate>
                <asp:ImageButton ID="LINKButton2" runat="server" 
                    CommandName="Edit" 
                    ImageUrl="img/edit.png" 
                    Style="vertical-align: text-bottom" />&nbsp;
                <asp:LinkButton ID="ButtonSelect" runat="server" 
                    CommandName="Select" 
                    CommandArgument='<%# Eval("ID") %>' 
                    Style="vertical-align: text-bottom; text-decoration: none" 
                    OnClick="AddNewMileStone" Visible="true">
                        <asp:Image runat="server" ID="ImageMS" 
                            ImageUrl="img/select.png" 
                            Style="vertical-align: text-bottom; text-decoration: none" 
                            BorderStyle="None" />
                </asp:LinkButton>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:ImageButton ID="InsertButton" runat="server" 
                    CommandName="Update" 
                    ImageUrl="img/save.png" 
                    Style="vertical-align: text-bottom" />&nbsp;&nbsp;
                <asp:ImageButton ID="LINKButton2" runat="server" 
                    CommandName="Cancel" 
                    ImageUrl="img/cancel2.jpg" 
                    Style="vertical-align: text-bottom" />
            </EditItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField ItemStyle-HorizontalAlign="center" 
            Visible="false">
        <ItemTemplate>
            <asp:LinkButton ID="ButtonOpen" runat="server" 
                CommandArgument = '<%# Eval("ID") %>' 
                OnClick="OpenNode" 
                style="vertical-align:text-bottom;text-decoration:none" 
                Visible="false">
                <asp:Image id="OpenNodeIMG" runat="server" 
                    src="img/plus_.png" 
                    border="0" 
                    Visible="true"/>
            </asp:LinkButton>
        </ItemTemplate>
    </asp:TemplateField>
    </Columns>
</asp:GridView>

【问题讨论】:

  • 是来自 OpenNode 事件处理程序的第一个 sn-p 吗?完整的方法是什么,究竟在哪里抛出异常?
  • 不,这是 OnRowDataBound 事件。并且在绑定 Grid 时抛出异常,并由设置 Gridview_ActionPlan.Columns[5].Visible = true
  • 我认为共享堆栈跟踪可能会有所帮助
  • 不知道你想要什么作为堆栈跟踪。我添加了整个 OnRowDataBound 方法。我基本上将所有内容都减少到最少的代码,以便更容易捕获
  • 也希望看到您的 gridview 标记

标签: c# gridview rowdatabound


【解决方案1】:

这有点费时间,所以如果有人有更好的想法,请随意......虽然这不是那个帖子的问题

其实这应该是个大问题。你在这里做错了三件事。

  1. 您正在调用该函数以在 RowDataBound 的每次迭代中填充数据集。如果您有 20 行和 1 个标题,这将是 20 次不必要的数据库调用
  2. 无需 open() 连接即可使用数据适配器填充数据集
  3. 无需使用 Cells[cell_index]` 限定 .FindControl

所以在您的 Gridviews DataBind() 事件之后移动您的代码。伪代码将是,

Gridview_ActionPlan.DataBind();
DataSet t = new DataSet();
var gv = Gridview_ActionPlan;
string GridID = Convert.ToString(gv.ID);

using (SqlConnection objConn = new SqlConnection("Data Source=XXXXXX"))
using (SqlCommand objCommand = new SqlCommand(@"select Text
                                    from EPC_Menu
                                    where language = @language and MenuControlID = @GridID
                                    order by MenuID", objConn))
{
    SqlDataAdapter adapter = new SqlDataAdapter();
    objCommand.Parameters.Add("@GridID", SqlDbType.NVarChar).Value = GridID;
    objCommand.Parameters.Add("@language", SqlDbType.NVarChar).Value = LanguageLabel.Text;
    adapter.SelectCommand = objCommand;
    adapter.Fill(t);
}

var headerRow = gv.HeaderRow;
for (int i = 0; i + 6 < gv.Columns.Count; i++)
{
    if (t.Tables[0].Rows.Count > 0)
    {
        headerRow.Cells[i + 6].Text = t.Tables[0].Rows[i][0].ToString();
    }
}
for (int i = 0; i < gv.Rows.Count; i++)
{
    if (gv.Rows[i].Cells[1].Text == "True")
    {
        gv.Rows[i].Cells[9].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
        gv.Rows[i].Cells[10].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
    }
    else if (gv.Rows[i].Cells[2].Text == "2")
    {
        gv.Rows[i].BackColor = System.Drawing.ColorTranslator.FromHtml("#CCECF4");
    }
    if (gv.Rows[i].Cells[3].Text != "1" && 
        gv.Rows[i].Cells[2].Text != "2" && 
        !string.IsNullOrEmpty(gv.Rows[i].Cells[3].Text) &&
        gv.Rows[i].RowType == DataControlRowType.DataRow && 
        Gridview_ActionPlan.EditIndex != gv.Rows[i].RowIndex)
    {
        LinkButton LB2 = gv.Rows[i].FindControl("ButtonOpen") as LinkButton;
        LB2.Visible = true;
    }
}

【讨论】:

  • 谢谢!你给了我很多投入和功课来学习。但是,如果我将此修改应用于我的代码,它会引发错误“堆栈不足以继续安全地执行程序”
  • 你知道这是在哪里发生的吗?
  • 不,不幸的是,不完全是。在加载那个gridview
  • 为了隔离错误,我消除了所有条件,只保留第一部分直到 var headerRow = gv.HeaderRow;网格未加载。它会尝试,但过了一段时间会抛出“堆栈不足,无法继续安全地执行程序”错误。可能还有另一个提示:我已将您发布的第一部分复制并粘贴到我的 OnRowDataBound 方法中,并且出现了该错误。直到那时我才意识到我没有更改我帖子中模糊的连接字符串(“XXXX”);尽管如此,这并没有引发错误。这意味着甚至没有尝试建立连接
  • 纳文,我有点迷路了。我看到你在每个单元格的每次迭代中不必要地调用函数的观点。但我看不出如何避免它,因为据我了解 OnRowDataBound 方法中的每一段代码都是在每个单元格上执行的。我不明白你的伪代码是如何工作的。现在我正在考虑以下内容:由于网格的填充是通过选择另一个网格的一行来触发的,所以我可以在 IndexSelectionChange 事件中使用标题填充一个不可见的辅助网格,然后在同时引用该辅助网格绑定Grid的标题行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 2021-01-10
  • 2017-12-22
  • 2014-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多