Reputation: 544
I'm trying to set some columns as ReadOnly in my GridView. As I'm using the same ASPX for several different views, I need to do this in back end code. I've seen several posts on this but not sure what I'm doing wrong. I'm getting the error Object reference not set to an instance of an object.
Here is my code:
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;
}
}
I have also tried the following with the same results.
TextBox txt = (TextBox)e.Row.FindControl("ID");
txt.ReadOnly = true;
I also tried the following and got the error Index was out of range. Must be non-negative and less than the size of the collection.
((BoundField)FormsGridView.Columns[1]).ReadOnly = true;
What am I doing wrong?
EDIT: GridView code added
<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 is also being done on the back end:
FormsGridView.AutoGenerateEditButton = true;
SqlDS1.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;
SqlDS1.UpdateCommand = ("SP");
What seems odd to me is that I can pull the values from cells using the following:
id = Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "ID"));
But when attempting to reference as a TextBox is when I get the Object reference not set to an instance of an object.
error.
TextBox txt = (DataBinder.Eval(e.Row.DataItem, "ID")) as TextBox;
txt.ReadOnly = true;
Just for kicks, I changed the name "ID" to "SomeID" which is not returned by the stored procedure and I do in fact get a different error as expected DataBinding: 'System.Data.DataRowView' does not contain a property with the name 'SomeID'.
Upvotes: 1
Views: 2961
Reputation: 544
Problem solved!
As I wasn't able to set AutoGenerateColumns="False" I was unable to set the columns to ReadOnly as I was attempting to do. So what I ended up doing was adding DataKeyNames in the code behind instead, for each of the columns I needed to be ReadOnly. So my code is like this:
FormsGridView.DataKeyNames = new string[] { "ID", "Name" };
I also moved this further up in my code where I assign some variables as I was receiving an error Cannot have multiple items selected in a DropDownList
if I assigned the DataKeyNames after my PageNumbers DropDownList which is created in the FormsGridView_DataBound function.
Upvotes: 0
Reputation: 6586
You are receiving the error because you are returning a null TextBox object and then trying to set it to read-only.
The TextBox controls won't be in the GridView unless you are in Edit Mode, so you need to check if the RowState is Edit. Note: The if
statement may need adjusting based on your GridView definition.
if (e.Row.RowState == DataControlRowState.Edit ||
e.Row.RowState == DataControlRowState.Alternate)
{
TextBox txt = (TextBox)e.Row.FindControl("ID");
txt.ReadOnly = true;
}
You can also reference this question: GridView template Column conditionally set to readonly
UPDATE You need to set AutoGenerateColumns = FALSE and define your columns. Look at this post: Allowing one column to be edited but not another
Upvotes: 1