这是this thread with how to build a DetailsView button that will check all the boxes in a given form.的延续我尝试在前一个帖子中获得帮助,但没有响应,因此新线程。
截至目前,复选框按钮无问题,但当我点击“保存”按钮时,此行的cs文件中会显示一条错误消息:
TextBox tb = FindControl<TextBox>(row.Cells[i].Controls);
if (tb != null)
{
table.Rows[0][j] = tb.Text;
}
错误:
System.NullReferenceException:未将对象引用设置为对象的实例。
我很难过,我在这里做错了什么。我想我不知道这个过程如何在幕后完全运作。我一直在倾注MSDN文档,看看我是否可以更好地解释如何在理论上正确地将其保存到数据库,但是无法找到合适的文档来帮助。
在我向代码添加复选框按钮之前,SQL代码是可靠的并且没有任何问题。
表格代码:
(Note some cosmetic code for the details view has been omitted)
<%@ Page Title="Test Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="form2.aspx.cs" Inherits="form2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" Runat="Server">
<asp:DetailsView ID="DetailsView" runat="server" AutoGenerateColumns="False" CellPadding="4" DataSourceID="SqlDataSource1" ForeColor="#333333" GridLines="None">
<AlternatingRowStyle BackColor="White" />
<insert asp cosmetic gobbledy gook here>
<Fields>
<asp:BoundField DataField="Field_1" HeaderText="Ticket Number" SortExpression="Field_1" />
<asp:BoundField DataField="Field 2" HeaderText="Field 2" SortExpression="Field_2" />
<asp:BoundField DataField="Field_3" HeaderText="Field 3" SortExpression="Field_3" />
<asp:BoundField DataField="Field_4" HeaderText="Field 4" SortExpression="Field_4" />
<asp:BoundField DataField="Field_5" HeaderText="Field 5" SortExpression="Field_5" />
<asp:BoundField DataField="Field_6" HeaderText="Field 6" SortExpression="Field_6" />
<asp:BoundField DataField="Field_7" HeaderText="Field 7" SortExpression="Field_7" />
<asp:BoundField DataField="Field_8" HeaderText="Field 8" SortExpression="Field_8" />
<asp:BoundField DataField="Field_9" HeaderText="Field 9" SortExpression="Field_9" />
<asp:BoundField DataField="Field_10" HeaderText="Field 10" SortExpression="Field_10" />
<asp:CheckBoxField DataField="Check_Box_1" HeaderText="Check Box 1" SortExpression="Check_Box_1" />
<asp:CheckBoxField DataField="Check_Box_2" HeaderText="Check Box 2" SortExpression="Check_Box_2" />
<asp:CheckBoxField DataField="Check_Box_3" HeaderText="Check Box 3" SortExpression="Check_Box_3" />
<asp:CheckBoxField DataField="Check_Box_4" HeaderText="Check Box 4" SortExpression="Check_Box_4" />
<asp:CheckBoxField DataField="Check_Box_5" HeaderText="Check Box 5" SortExpression="Check_Box_5" />
<asp:CheckBoxField DataField="Check_Box_6" HeaderText="Check Box 6" SortExpression="Check_Box_6" />
<asp:CheckBoxField DataField="Check_Box_7" HeaderText="Check Box 7" SortExpression="Check_Box_7" />
<asp:CheckBoxField DataField="Check_Box_8" HeaderText="Check Box 8" SortExpression="Check_Box_8" />
<asp:CheckBoxField DataField="Check_Box_9" HeaderText="Check Box 9" SortExpression="Check_Box_9" />
<asp:CheckBoxField DataField="Check_Box_10" HeaderText="Check Box 10" SortExpression="Check_Box_10" />
<asp:CheckBoxField DataField="Check_Box_11" HeaderText="Check Box 11" SortExpression="Check_Box_11" />
<asp:CheckBoxField DataField="Check_Box_12" HeaderText="Check Box 12" SortExpression="Check_Box_12" />
<asp:CheckBoxField DataField="Check_Box_13" HeaderText="Check Box 13" SortExpression="Check_Box_13" />
<asp:CheckBoxField DataField="Check_Box_14" HeaderText="Check Box 14" SortExpression="Check_Box_14" />
<asp:CheckBoxField DataField="Check_Box_15" HeaderText="Check Box 15" SortExpression="Check_Box_15" />
<asp:CheckBoxField DataField="Check_Box_16" HeaderText="Check Box 16" SortExpression="Check_Box_16" />
<asp:CheckBoxField DataField="Check_Box_17" HeaderText="Check Box 17" SortExpression="Check_Box_17" />
<asp:CheckBoxField DataField="Check_Box_18" HeaderText="Check Box 18" SortExpression="Check_Box_18" />
<asp:CheckBoxField DataField="Check_Box_19" HeaderText="Check Box 19" SortExpression="Check_Box_19" />
<asp:ButtonField ButtonType="Button" CommandName="btnSelectAll" Text="Select/Check All Servers" >
<asp:BoundField DataField="Field_11" HeaderText="Field 11" SortExpression="Field_11" />
<asp:BoundField DataField="Field_12" HeaderText="Field 12" SortExpression="Field_12" />
<asp:BoundField DataField="Field_13" HeaderText="Field 13" SortExpression="Field_13" />
<asp:ButtonField ButtonType="Button" CommandName="btnCancel" Text="Cancel" />
<asp:ButtonField ButtonType="Button" CommandName="btnSave" Text="Save" />
<asp:CommandField ButtonType="Button" NewText="CreateRecord" ShowInsertButton="True" />
</Fields>
<more asp non essential cosmetic gobbledy gook>
</asp:DetailsView>
<asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:test_form_connect %>" runat="server" InsertCommand="INSERT INTO [test].[detailsview_test_form] ([Field_1], [Field_2], [Field_3], [Field_4], [Field_5], [Field_6], [Field_7], [Field_8], [Field_9], [Field_10], [Check_Box_1], [Check_Box_2], [Check_Box_3], [Check_Box_4], [Check_Box_5], [Check_Box_6], [Check_Box_7], [Check_Box_8], [Check_Box_9], [Check_Box_10], [Check_Box_11], [Check_Box_12], [Check_Box_13], [Check_Box_14], [Check_Box_15], [Check_Box_16], [Check_Box_17], [Check_Box_18], [Check_Box_19], [Field_11], [Field_12], [Field_13]) VALUES (@Field_1, @Field_2, @Field_3, @Field_4, @Field_5, @Field_6, @Field_7, @Field_8, @Field_9, @Field_10, @Check_Box_1, @Check_Box_2, @Check_Box_3, @Check_Box_4, @Check_Box_5, @Check_Box_6, @Check_Box_7, @Check_Box_8, @Check_Box_9, @Check_Box_10, @Check_Box_11, @Check_Box_12, @Check_Box_13, @Check_Box_14, @Check_Box_15, @Check_Box_16, @Check_Box_17, @Check_Box_18, @Check_Box_19, @Field_11, @Field_12, @Field_13) ">
<InsertParameters>
<asp:Parameter Name="Field_1" />
<asp:Parameter Name="Field_2" />
<asp:Parameter Name="Field_3" />
<asp:Parameter Name="Field_4" />
<asp:Parameter Name="Field_5" />
<asp:Parameter Name="Field_6" />
<asp:Parameter Name="Field_7" />
<asp:Parameter Name="Field_8" />
<asp:Parameter Name="Field_9" />
<asp:Parameter Name="Field_10" />
<asp:Parameter Name="Check_Box_1" />
<asp:Parameter Name="Check_Box_2" />
<asp:Parameter Name="Check_Box_3" />
<asp:Parameter Name="Check_Box_4" />
<asp:Parameter Name="Check_Box_5" />
<asp:Parameter Name="Check_Box_6" />
<asp:Parameter Name="Check_Box_7" />
<asp:Parameter Name="Check_Box_8" />
<asp:Parameter Name="Check_Box_9" />
<asp:Parameter Name="Check_Box_10" />
<asp:Parameter Name="Check_Box_11" />
<asp:Parameter Name="Check_Box_12" />
<asp:Parameter Name="Check_Box_13" />
<asp:Parameter Name="Check_Box_14" />
<asp:Parameter Name="Check_Box_15" />
<asp:Parameter Name="Check_Box_16" />
<asp:Parameter Name="Check_Box_17" />
<asp:Parameter Name="Check_Box_18" />
<asp:Parameter Name="Check_Box_19" />
<asp:Parameter Name="Field_11" />
<asp:Parameter Name="Field_12" />
<asp:Parameter Name="Field_13" />
</InsertParameters>
</asp:SqlDataSource>
</asp:Content>
背后的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
public partial class checkbox_dev : System.Web.UI.Page
{
DataTable m_table = null;
public DataTable table
{
get
{
if (ViewState["m_table"] != null)
return (DataTable)ViewState["m_table"];
else
return null;
}
set
{
ViewState["m_table"] = value;
}
}
public static T FindControl<T>(ControlCollection controls)
{
for (int i = 0; i < controls.Count; i++)
{
if (controls[i] is T)
return (T)(object)controls[i];
}
return default(T);
}
protected void Page_Load(object sender, EventArgs e)
//private static DataTable GetData(string sqlCommand)
{
string connectionString = GetConnectionString();
SqlConnection connection = new SqlConnection(connectionString);
}
static private string GetConnectionString()
{
return "(insert SQL Server connection Stringhere)";
}
protected void DetailsView1_ItemCommand(Object sender, DetailsViewCommandEventArgs e)
{
if (e.CommandName == "btnSelectAll")
{
foreach (DetailsViewRow row in DetailsView1.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
CheckBox cb = FindControl<CheckBox>(row.Cells[i].Controls);
if (cb != null)
{
cb.Checked = true;
}
}
}
}
if (e.CommandName == "btnSave")
{
int j = 0;
foreach (DetailsViewRow row in DetailsView1.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
TextBox tb = FindControl<TextBox>(row.Cells[i].Controls);
if (tb != null)
{
table.Rows[0][j] = tb.Text;
}
CheckBox cb = FindControl<CheckBox>(row.Cells[i].Controls);
if (cb != null)
{
table.Rows[0][j] = cb.Checked;
}
}
j++;
}
DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
DetailsView1.DataSource = table;
DetailsView1.DataBind();
}
if (e.CommandName == "btnEdit")
{
DetailsView1.ChangeMode(DetailsViewMode.Edit);
DetailsView1.DataSource = table;
DetailsView1.DataBind();
}
if (e.CommandName == "btnCancel")
{
DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
DetailsView1.DataSource = table;
DetailsView1.DataBind();
}
}
}
答案 0 :(得分:0)
我认为对我来说最大的问题是你的代码在你的语法中假设row.Cells[i].Controls
。您应该检查以确保单元格具有“控件”集合。
看看这段代码,我的初始传感器变得疯狂。
if (e.CommandName == "btnSave")
{
int j = 0;
foreach (DetailsViewRow row in DetailsView1.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
TextBox tb = FindControl<TextBox>(row.Cells[i].Controls);
if (tb != null)
{
table.Rows[0][j] = tb.Text;
}
CheckBox cb = FindControl<CheckBox>(row.Cells[i].Controls);
if (cb != null)
{
table.Rows[0][j] = cb.Checked;
}
}
j++;
}
你上面所做的,实质上是将一个类型的变量'int'初始化为0(int j = 0;
),但是你增加它,而不考虑你以后试图访问的列集合索引上面的代码,table.Rows[0][j] = cb.Checked;
代表'DetailsView1.Rows'的每一行。
所以基本上你正在做的是在DetailsView1.Rows中每行递增1,并试图通过该索引访问DataTable的'Columns'。但是,如果该索引中不存在列,该怎么办?
我建议在过渡期间解决问题的一件事是在使用之前检查“Cells”集合中是否存在单元格。像这样......
if (table.Rows[0][j] != null)
{
table.Rows[0][j] = tb.Text;
}
这只是一个乐队援助修复,不应该长期使用,因为可能迭代超过集合范围的根本问题不是真正可以接受的实践。我需要一些时间来分析你的方法和重构。是的,对于您来说,单元格应该全部存在可能是有意义的,因为您的详细信息视图的行数小于DataTable的单元格,但它仍然不是很好的做法,并且可能是您在此处出错的原因。