1

質問する前にいくつかの検索を行いましたが、この投稿は近いですが、私のシナリオでは機能しません.

私が見つけたのは、テンプレート フィールドの「削除」ボタンが起動しているように見えますが、クリック イベントはトリガーされません。それでも、ボタンを 2 回クリックすると、期待どおりに機能します。

したがって、コードを分解するとGridView、「SqlDataSource.

マイページの読み込みイベントは次のように開始されます。

if (!Page.IsPostBack)  
{  
    externalUserDataSource.ConnectionString = "some connection string";  
}

私のデータソースは次のとおりです。

<asp:SqlDataSource ID="externalUserDataSource" runat="server" 
    ConflictDetection="CompareAllValues" SelectCommand="uspGetExternalUsersByTeam"
SelectCommandType="StoredProcedure" ProviderName="System.Data.SqlClient">
<SelectParameters>
    <asp:SessionParameter Name="TeamID" SessionField="TeamID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>

そして、これは私のGridViewマークアップです:

<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" 
    BackColor="White" BorderColor="#3366CC" BorderStyle="None" BorderWidth="1px" 
    CellPadding="4" DataKeyNames="LoginID" DataSourceID="externalUserDataSource" 
    EnableModelValidation="True" OnRowDataBound="GridViewRowDataBound" TabIndex="3">
        <HeaderStyle BackColor="#003399" Font-Bold="True" ForeColor="White" />
        <FooterStyle BackColor="#99CCCC" ForeColor="#003399" />
        <PagerStyle BackColor="#99CCCC" ForeColor="#003399" HorizontalAlign="Left" />
        <RowStyle BackColor="LightGoldenrodYellow" />
        <SelectedRowStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" />
        <Columns>
            <asp:BoundField DataField="RowID" HeaderText="Row ID" ReadOnly="True" 
                SortExpression="RowID" Visible="False" />
            <asp:BoundField DataField="LoginID" HeaderText="Login ID" ReadOnly="True" 
                SortExpression="LoginID" Visible="False" />
            <asp:BoundField DataField="EmailAddress" HeaderText="Email Address" 
                ItemStyle-VerticalAlign="Bottom" ReadOnly="True" SortExpression="AssociateName"/>
            <asp:BoundField DataField="TeamID" HeaderText="Team ID" ReadOnly="True" 
                SortExpression="TeamID" Visible="False" />
            <asp:CheckBoxField DataField="HasFIAccess" 
                 HeaderText="Has Access to&lt;br /&gt;Funding&lt;br/&gt;Illustrator" 
                 ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Bottom" 
                 ReadOnly="True"/>
            <asp:CheckBoxField DataField="HasALTAccess" 
                 HeaderText="Has Access to&lt;br /&gt;Asset Liability&lt;br/&gt;Tracker" 
                 ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Bottom"
                 ReadOnly="True"/>
            <asp:CheckBoxField DataField="HasFIAAccess" 
                 HeaderText="Has Access to&lt;br /&gt;Funding&lt;br/&gt;Illustrator App" 
                 ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Bottom"
                 ReadOnly="True"/>                    
            <asp:TemplateField>
            <ItemTemplate>
                <asp:Button runat="server" CssClass="additionsRow" ID="btnDeleteExternalUser" OnClick="DeleteExtUserButtonClick" 
                    CausesValidation="False" Text="Delete" 
                    CommandArgument='<%#Eval("TeamID") + "," + Eval("LoginID") + "," + Eval("EmailAddress") + "," + Eval("HasALTAccess")%>'/>                            
            </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

したがって、正しいデータが削除されるようにイベントで使用されるボタンにいくつかの情報を渡していることがわかります (ButtonField上記のリンクで提案されているように、 を使用できないのはそのためです)。

パズルの最後の部分は、GridViewのデータバインド イベントです。

        protected void GridViewRowDataBound(object sender, 
                                        GridViewRowEventArgs e)
    {
        // if rowtype is not data row...
        if (e.Row.RowType != DataControlRowType.DataRow)
        {
            // exit with no further processing...
            return;
        }

        // get the ID for the selected record...
        var selectedId = DataBinder.Eval(e.Row.DataItem, "RowID").ToString();

        // create unique row ID...
        e.Row.ID = string.Format("ExtUserRow{0}", selectedId);

        // find the button delete for the selected row...
        var deleteButton = (Button)e.Row.FindControl("btnDeleteExtUser");

        // get the email address for the selected record...
        var selectedUser = DataBinder.Eval(e.Row.DataItem, "EmailAddress").ToString();

        // define the message text...
        var messageText = string.Format("OK to delete {0}?",
                                        selectedUser.Replace("'", "\\'")); 

        // add attribute to row delete action...
        this.AddConfirmMessage(deleteButton, messageText);
    }  

AddConfirmMessageユーザーが削除を確認する必要があることを確認するために、コントロールに onclick 属性を割り当てるだけです。

いずれの場合も、「abc@xyz.com を削除してもよろしいですか? 」というメッセージが表示されます。ただし、前述のように、「削除」ボタンに割り当てられたイベントは、ボタンが 2 回クリックされるまでトリガーされません。

奇妙なことに、別のページからこのコードを取得し、それに応じて変更しましたが、この問題はありません。

        protected void DeleteExtUserButtonClick(object sender, 
                                            EventArgs e)
    {
        // get the buton which was clicked...
        var button = (Button)sender;

        // break the delimited array up...
        string[] argumentArray = button.CommandArgument.Split(',');

        // store the items from the array...
        string teamId = argumentArray[0];
        string loginId = argumentArray[1];
        string emailAddress = argumentArray[2];
        string hasAltAccess = argumentArray[3];

        using (var conn = new SqlConnection(Utils.GetConnectionString()))
        {
            // create database command...
            using (var cmd = new SqlCommand())
            {
                // set the command type...
                cmd.CommandType = CommandType.StoredProcedure;

                // set the name of the stored procedure to call...
                cmd.CommandText = "uspDeleteExternalUser";

                // create and add parameter to the collection...
                cmd.Parameters.Add(new SqlParameter("@TeamId", SqlDbType.Int));

                // assign the search value to the parameter...
                cmd.Parameters["@TeamId"].Value = teamId;

                // create and add parameter to the collection...
                cmd.Parameters.Add(new SqlParameter("@LoginId", SqlDbType.VarChar, 50));

                // assign the search value to the parameter...
                cmd.Parameters["@LoginId"].Value = loginId;

                // set the command connection...
                cmd.Connection = conn;

                // open the connection...
                conn.Open();

                // perform deletion of user...
                cmd.ExecuteNonQuery();
            }
        }

        // bind control to refresh content...
        ExtUsersGrid.DataBind();
    }

明らかな何かを見逃しましたか?これを行うためのより良い方法があれば、私は喜んで変更します。

編集1:以下の議論に続いて、私は以下を修正しました:

  • Onclickのイベント プロパティを削除しましたButtonItem
  • CommandName以下に示すようにとを設定し、データからの一意の ID である RowID を使用する CommandArgumentように を更新しました。DataKeyNames
  • RowCommandのイベントを割り当てましたGridView
  • イベントに削除コードを割り当てましたRowCommand

これらの変更後も、2 回目のクリックで行イベント コードが発生します。

編集 2 :FYI - および関連するコード/参照を削除し、(括弧内で)SqlDataSource呼び出されるデータセットを埋める手順を作成しました。イベントを使用するために以下の変更を開始しましたが、それでも同じ問題が発生しました (つまり、ボタンは 2 回目のクリックでのみ起動します)。を使用するということはs をs に変換することを意味するので、ボタン クリック イベントに戻りました。2回目のクリックでのみトリガーされる理由を他の誰かが理解するのを手伝ってくれるなら、あなたの意見をいただければ幸いです。Page_Load!Page.IsPostBackRowCommandRowCommandBoundFieldItemTemplate

4

2 に答える 2

3

OK、イライラすることに、これは理由は不明ですが、他の場所で動作するコードが原因でした。
DataBound イベントには、次の 2 行のコードがありました。

        // get the associate name for the selected record...
        var selectedId = DataBinder.Eval(e.Row.DataItem, "RowID").ToString();
        // create unique row ID...
        e.Row.ID = string.Format("ExtUserRow{0}", selectedId);  

ID をプログラムで行に適用するプロセスは、データとイベントの間の接続を切断するようです。
この 2 行のコードを削除すると、期待どおりに動作します。

于 2013-03-04T18:00:48.323 に答える
-1

代わりに、このようなことができます。

CommandNameこのようにプロパティを追加しますGridViewCommandArgumentプロパティの変更にも注意してください。

<asp:TemplateField>
    <ItemTemplate>
        <asp:Button runat="server" CssClass="additionsRow" ID="btnDeleteExtUser"  
                    CausesValidation="False" Text="Delete" 
                    CommandName="OnDelete"  
                    CommandArgument='<%# Container.DisplayIndex %>" '                              
</ItemTemplate>
</asp:TemplateField>

コードビハインドは次のようになります。RowCommandのイベントを使用していることに注意してくださいGridview

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if(e.CommandName == "OnDelete")
    {
        int rowIndex = Convert.ToInt32(e.CommandArgument);
        // now you got the rowindex, write your deleting logic here.
        int ID = Convert.ToInt32(myGrid.DataKeys[rowIndex]["ID"].Value);
        // id will return you the id of the row you want to delete 
        TextBox tb = (TextBox)GridView1.Rows[rowIndex].FindControl("textboxid");
        string text = tb.Text;
        // This way you can find and fetch the properties of controls inside a `GridView`. Just that it should be within `ItemTemplate`.
    }
} 

注:DataKeyNames="ID"内に言及してくださいGridView。「ID」は、テーブルの主キー列です。

ページロード時にバインドしGridViewていますか? !IsPostBackその場合は、以下に示すようにブロックに移動します。

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        GridView1.DataSource = yourDataSource;
        GridView1.DataBind();           
    } 
}
于 2013-03-04T11:30:39.677 に答える