0

これは、特定のフォーム内のすべてのボックスをチェックする DetailsView ボタンを作成する方法に関するこのスレッドの続きです。 以前のスレッドで支援を得ようとしましたが、応答がなかったため、新しいスレッドになりました。

現時点では、チェックボックス ボタンは問題なく動作しますが、[保存] ボタンをクリックすると、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();
    }
}

}
4

1 に答える 1

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 の「列」にアクセスしようとしています。しかし、そのインデックスに列が存在しない場合はどうなるでしょうか?

当面の問題を解決するために私が提案することの1つは、使用する前に「セル」コレクションにセルが存在することを確認することです。このような...

if (table.Rows[0][j] != null)
{
    table.Rows[0][j] = tb.Text;
}

これは単なる応急処置であり、コレクションの境界を超えて反復する可能性があるという基本的な問題は実際には受け入れられないため、長期的に使用するべきではありません。少し時間をかけて、方法論とリファクタリングを分析します。はい、詳細ビューの行が DataTable のセルよりも少ないため、セルがすべて存在する必要があることは理にかなっているかもしれませんが、それでも良い方法ではなく、ここでエラーの原因になる可能性があります。

于 2013-10-09T04:19:56.847 に答える