【问题标题】:Gridview Set Column ReadOnly ProgrammaticallyGridview 以编程方式设置列只读
【发布时间】:2015-07-15 18:50:24
【问题描述】:

我正在尝试在我的 GridView 中将某些列设置为只读。由于我对几个不同的视图使用相同的 ASPX,因此我需要在后端代码中执行此操作。我已经看过几篇关于此的帖子,但不确定我做错了什么。我收到错误 Object reference not set to an instance of an object.

这是我的代码:

protected void FormsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        TextBox txt = (DataBinder.Eval(e.Row.DataItem, "ID")) as TextBox;
        txt.ReadOnly = true;
    }
}

我也尝试了以下相同的结果。

TextBox txt = (TextBox)e.Row.FindControl("ID");
txt.ReadOnly = true;

我也尝试了以下并得到错误Index was out of range. Must be non-negative and less than the size of the collection.

((BoundField)FormsGridView.Columns[1]).ReadOnly = true;

我做错了什么?

编辑:添加了 GridView 代码

<asp:GridView ID="FormsGridView" runat="server" 
    DataSourceID="SqlDS1" OnDataBound="FormsGridView_DataBound" AllowPaging="True" 
    AllowSorting="True" PageSize="1000" onprerender="GridView_PreRender" 
    CssClass="GridView" onrowcreated="FormsGridView_RowDataBound">
    <PagerSettings Position="Top" />
    <Columns>
        <asp:TemplateField ItemStyle-Wrap="False">
            <ItemTemplate>
                <asp:HyperLink ID="DeleteButton" runat="server">
                    <img  src="images/delete.png" alt="Delete Item" width="16px" height="16px" style="cursor:pointer;vertical-align:bottom;text-decoration:none" /></asp:HyperLink>
                <asp:HyperLink ID="EditButton" runat="server">
                    <img  src="images/edit.png" alt="Edit Item" width="16px" height="16px" style="cursor:pointer;vertical-align:bottom;text-decoration:none" /></asp:HyperLink>
            </ItemTemplate>
        </asp:TemplateField>    
    </Columns>
    <PagerTemplate>
        <div class="pages">
            <asp:DropDownList ID="PagingDropDownList" runat="server" AutoPostBack="true"
            OnSelectedIndexChanged="PagingDropDownList_SelectedIndexChanged" height="30px" />
        </div>
    </PagerTemplate>
</asp:GridView>

UpdateCommand 也在后端完成:

FormsGridView.AutoGenerateEditButton = true;
SqlDS1.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;
SqlDS1.UpdateCommand = ("SP");

我觉得奇怪的是,我可以使用以下方法从单元格中提取值:

id = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "ID"));

但是当我尝试作为 TextBox 引用时,我得到了 Object reference not set to an instance of an object. 错误。

TextBox txt = (DataBinder.Eval(e.Row.DataItem, "ID")) as TextBox;
txt.ReadOnly = true;

只是为了好玩,我将名称“ID”更改为存储过程不返回的“SomeID”,实际上我确实得到了一个与预期不同的错误DataBinding: 'System.Data.DataRowView' does not contain a property with the name 'SomeID'.

【问题讨论】:

  • 请发布您的 GridView 标记。
  • 根据您的错误,显然没有找到您的控件Id。您的语法看起来有效,但我们需要查看您的 Grid 语法。
  • @Greg 按要求添加了 GridView
  • @doby48 你的Id 控件/文本框在哪里,我在你的代码中看不到它。
  • @Greg 我的 ASPX 中没有文本框,我正在使用 AutoGenerateColumns,这看起来是这里的问题。我找到了一个解决方案,采用不同的方式将某些列设置为 ReadOnly,并将其添加为下面的答案。

标签: c# asp.net gridview


【解决方案1】:

您收到错误是因为您正在返回一个空 TextBox 对象,然后尝试将其设置为只读。

除非您处于编辑模式,否则 TextBox 控件不会在 GridView 中,因此您需要检查 RowState 是否为 Edit。注意:if 语句可能需要根据您的 GridView 定义进行调整。

if (e.Row.RowState == DataControlRowState.Edit ||
    e.Row.RowState == DataControlRowState.Alternate)
{
    TextBox txt = (TextBox)e.Row.FindControl("ID");
    txt.ReadOnly = true;
}

也可以参考这个问题:GridView template Column conditionally set to readonly

更新 您需要设置 AutoGenerateColumns = FALSE 并定义您的列。 看这个帖子:Allowing one column to be edited but not another

【讨论】:

  • 我看到了那个帖子并尝试过,但没有成功。我也尝试了您提供的代码,但仍然收到相同的错误。
  • 根据要求编辑了原始帖子以包含 GridView。
  • 我现在看到了 GridView 标记。文本框在哪里,我没看到?
【解决方案2】:

问题解决了!

由于我无法设置 AutoGenerateColumns="False" 我无法将列设置为 ReadOnly,因为我正在尝试这样做。所以我最终做的是在后面的代码中添加 DataKeyNames,而不是为我需要只读的每一列。所以我的代码是这样的:

FormsGridView.DataKeyNames = new string[] { "ID", "Name" };

我还在我的代码中将它进一步向上移动,我在收到错误 Cannot have multiple items selected in a DropDownList 时分配了一些变量,如果我在 FormsGridView_DataBound 函数中创建的 PageNumbers DropDownList 之后分配了 DataKeyNames。

【讨论】:

    猜你喜欢
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    • 2012-12-08
    • 2012-01-29
    • 2016-07-03
    • 2010-09-17
    相关资源
    最近更新 更多