所以我有一个gridview,我在后面的代码中填充,听取下拉以了解要填充的内容。那部分工作正常。但是当我从gridview中触发rowediting事件时,数据绑定进程会抛出NullReferenceException错误。
以下是页面:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div id="categories">
<h1>Categories</h1>
<asp:DropDownList ID="ddlCategories"
runat="server"
OnSelectedIndexChanged="ddlCategories_SelectedIndexChanged"
AutoPostBack="true"></asp:DropDownList>
</div>
<div id="products">
<h1>Products</h1>
<asp:GridView ID="gvProducts"
runat="server"
AutoGenerateColumns="false"
OnRowEditing="gvProducts_RowEditing"
AutoGenerateDeleteButton="True"
AutoGenerateEditButton="True"
OnRowCancelingEdit="gvProducts_RowCancelingEdit"
OnRowUpdating="gvProducts_RowUpdating">
<Columns>
<asp:BoundField
DataField="Category.Name"
HeaderText="Category" />
<asp:BoundField
Datafield="Name"
HeaderText="Name"/>
<asp:BoundField
Datafield="Description"
HeaderText="Description"/>
<asp:BoundField
DataField="Price"
HeaderText="Price"
DataFormatString="{0:c}"
HtmlEncode="False"/>
<asp:ImageField
DataImageUrlField="ImageURL"
HeaderText="Picture"></asp:ImageField>
<asp:CheckBoxField
DataField="Active"
Text="Active"
HeaderText="Status"/>
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
这是背后的代码:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindCategoryList();
BindProductList();
}
}
protected void BindCategoryList()
{
ddlCategories.DataTextField = "Name";
ddlCategories.DataValueField = "CategoryID";
ddlCategories.DataSource = CategoryDB.GetCategories();
ddlCategories.DataBind();
ddlCategories.Items.Insert(0, new ListItem(string.Empty));
ddlCategories.SelectedIndex = 0;
}
protected void BindProductList(int categoryID = 0)
{
gvProducts.DataSource = ProductDB.GetProductsByCategory(categoryID);
gvProducts.DataBind();
}
protected void ddlCategories_SelectedIndexChanged(object sender, EventArgs e)
{
BindProductList(Int32.Parse(ddlCategories.SelectedValue));
}
protected void gvProducts_RowEditing(object sender, GridViewEditEventArgs e)
{
gvProducts.EditIndex = e.NewEditIndex;
BindProductList(Int32.Parse(ddlCategories.SelectedValue));
}
错误发生在BindProductList()方法中,但仅在从gvProducts_RowEditing调用时发生。否则,它工作正常。当我调试时,我可以看到它肯定传递了正确的categoryID值,并且在DataBind调用之前它不会抛出错误,这意味着它仍然可以为DataSource()调用找到gvProducts。
有什么想法吗?感谢。
编辑:这是categorydb类和getcategories方法。
public class CategoryDB
{
public static List<Category> GetCategories()
{
using (var db = new ProductContext())
{
return (from c in db.Categories
orderby c.Name
select c).ToList<Category>();
}
}
答案 0 :(得分:1)
我不确定,但我认为您需要为每一列提供此功能,我认为您缺少要编辑的行
<asp:TemplateField headertext="Category.Name">
<ItemTemplate> <%#Eval("Category.Name")%></ItemTemplate>
<EditItemTemplate>
<asp:TextBox id="txtCategory.Name" runat="server" Enabled="False" text='<%#Eval("Category.Name")%>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="Category.Name" runat="server"> </asp:TextBox>
</FooterTemplate >
</asp:TemplateField>
我不确定你是如何调用编辑的,但我会为它添加另一个列
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="btnedit" runat="server" CommandName="Edit" Text="Edit"/>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="btnupdate" runat="server" CommandName="Update" Text="Update" />
<asp:LinkButton ID="btncancel" runat="server" CommandName="Cancel" Text="Cancel"/>
<asp:LinkButton ID="btnDelete" runat="server" CommandName="Delete" Text="Delete"/>
</EditItemTemplate>
<FooterTemplate>
<asp:Button ID="btnInsert" runat="Server" Text="Insert" CommandName="Insert" UseSubmitBehavior="False" />
</FooterTemplate>
</asp:TemplateField>
答案 1 :(得分:1)
其他人可能已经解决了你的问题,但这是另一个建议。我之前遇到过ddl的SelectedValue属性问题,所以你可以尝试使用:
BindProductList(Int32.Parse(ddlCategories.SelectedItem.Value));
你说你的功能在被叫到其他地方时起作用了,对吧?它只适用于页面加载还是选定的索引更改也可以工作?
出于好奇,你为什么要在编辑活动中使用ddl中的ID?我认为你会想要使用从你正在编辑的行派生的类别。
答案 2 :(得分:0)
您可能希望将GridViewEditEventArgs.Cancel
属性设置为true。
答案 3 :(得分:0)
这里有一个空值设置为ListItem,这意味着您的Dropdown项目将是Text =“”和Value =“”
ddlCategories.Items.Insert(0, new ListItem(string.Empty));
您的ddlCategories.SelectedValue可能是“”。如果ProductDB.GetProductsByCategory方法没有带回任何记录,它将绑定一个空白结果集,然后尝试在不再存在的索引上将网格置于编辑模式。
检查一下,看看它是否能让你深入了解那里可能发生的事情。
通常我将DropDownLists中的占位符值设置为
ddlCategories.Items.Insert(0, new ListItem("Select a category", "0"))
或
ddlCategories.Items.Insert(0, new ListItem("", "NULL"))
然后,在我进行值解析之前,我总是可以执行if语句,以确保在选择有效的内容后没有选择占位符值。
在这种情况下,如果你总是期待int
,那么第一个语句可能是更好的选择,因此你知道你永远不会解析空字符串或你用作字符串作为int的任何填充值。
答案 4 :(得分:0)
因为我意识到你的网格在UpdatePanel中,所以想到别的东西。看起来你遇到的问题与我以前遇到过的问题类似(不完全相同,但似乎可能是相关的)Gridview Row Events not firing in UserControl
将Grid从更新面板中取出并尝试,我打赌它会正常工作。我用来查找问题的参考是这个链接here
当您的DataSource发生更改并且您正在重新绑定异步调用时,可能会覆盖其ID,因此您的ScriptManager会丢失它对回调中前一行的引用。特别是如果您的数据源正在发生变化。
我发现UpdatePanels不值得,特别是在处理这些问题时。如果您仍然开始使用它,请查看我的问题,以了解我是如何设法解决问题的。它不是很漂亮,我的情况涉及动态控制,但也许它会有所帮助。
答案 5 :(得分:0)
找到它。错误发生在ImageField列中。数据库中的值为null,这在尝试编辑时显然是个问题。 当我注释掉ImageField时,它工作正常。我必须弄清楚如何处理它。