Gridview 以编程方式将列设置为只读
Gridview Set Column ReadOnly Programmatically
我正在尝试将我的 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"));
但是当我尝试作为文本框进行引用时,出现 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'.
您收到错误消息是因为您返回了一个空的 TextBox 对象,然后试图将其设置为只读。
除非您处于编辑模式,否则 TextBox 控件不会出现在 GridView 中,因此您需要检查 RowState 是否为编辑。注意: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 并定义您的列。
看看这个 post:Allowing one column to be edited but not another
问题已解决!
因为我无法设置 AutoGenerateColumns="False",所以我无法像我尝试的那样将列设置为 ReadOnly。所以我最终做的是在后面的代码中添加 DataKeyNames,因为我需要将每个列设为只读。所以我的代码是这样的:
FormsGridView.DataKeyNames = new string[] { "ID", "Name" };
如果我在 FormsGridView_DataBound 函数中创建的 PageNumbers DropDownList 之后分配了 DataKeyNames,我还在我的代码中进一步移动了它,我分配了一些变量,因为我收到错误 Cannot have multiple items selected in a DropDownList
.
我正在尝试将我的 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"));
但是当我尝试作为文本框进行引用时,出现 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'.
您收到错误消息是因为您返回了一个空的 TextBox 对象,然后试图将其设置为只读。
除非您处于编辑模式,否则 TextBox 控件不会出现在 GridView 中,因此您需要检查 RowState 是否为编辑。注意: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 并定义您的列。 看看这个 post:Allowing one column to be edited but not another
问题已解决!
因为我无法设置 AutoGenerateColumns="False",所以我无法像我尝试的那样将列设置为 ReadOnly。所以我最终做的是在后面的代码中添加 DataKeyNames,因为我需要将每个列设为只读。所以我的代码是这样的:
FormsGridView.DataKeyNames = new string[] { "ID", "Name" };
如果我在 FormsGridView_DataBound 函数中创建的 PageNumbers DropDownList 之后分配了 DataKeyNames,我还在我的代码中进一步移动了它,我分配了一些变量,因为我收到错误 Cannot have multiple items selected in a DropDownList
.