ASP.NET 利用数据网格模板列中图像按钮的单击事件

问题描述 投票:0回答:1

我正在努力让数据网格对我来说很好地工作。我意识到可能还有其他控件可以完成我的计划,但我对数据网格很了解,所以想看看这是否可行。本质上我有以下绑定到 SQL 连接的数据网格:

<asp:datagrid ID="dginventory" AutoGenerateColumns="false" runat="server" Width="99.4%" AllowPaging="True" AllowSorting="true" PageSize="20" OnPageIndexChanged="ChangePage" OnSortCommand="SortGrid" OnEditCommand="dginventory_oneditcommand" OnDeleteCommand="dginventory_ondeletecommand" >
            <HeaderStyle CssClass="datagridheader"/>
            <AlternatingItemStyle CssClass="datagridalternating"/>
            <ItemStyle cssClass="datagriditem"/>
            <Columns>
                <asp:BoundColumn DataField="PurchaseYear" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="center" HeaderText="YOP" ItemStyle-Width="4%" SortExpression="PurchaseYear ASC" />
                <asp:BoundColumn DataField="PurchaseDate" ItemStyle-HorizontalAlign="Center" HeaderText="Purchased" ItemStyle-Width="7%" DataFormatString="{0:d}" SortExpression="PurchaseDate ASC" />
                <asp:BoundColumn DataField="Number" HeaderText="Number" ItemStyle-Width="5%"  SortExpression="Number ASC" />
                <asp:BoundColumn DataField="Theme" HeaderText="Theme" ItemStyle-Width="10%" SortExpression="Theme ASC" />
                <asp:BoundColumn DataField="Name" HeaderText="Name" ItemStyle-Width="30%" SortExpression="Name ASC" />
                <asp:BoundColumn DataField="RRP" ItemStyle-HorizontalAlign="Left" HeaderText="RRP" ItemStyle-Width="4%" DataFormatString="{0:C}" />
                <asp:BoundColumn DataField="PurchasePrice" ItemStyle-HorizontalAlign="Left" HeaderText="Cost" ItemStyle-Width="4%" DataFormatString="{0:C}" />
                <asp:BoundColumn DataField="Discount" ItemStyle-HorizontalAlign="Left" HeaderText="Dis." ItemStyle-Width="4%" DataFormatString="{0:P1}" />
                <asp:BoundColumn DataField="ReleaseDate" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="center" HeaderText="Rel. Date" ItemStyle-Width="7%" DataFormatString="{0:d}" SortExpression="ReleaseDate ASC" />
                <asp:BoundColumn DataField="RetireDate" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="center" HeaderText="Ret. Date" ItemStyle-Width="7%" DataFormatString="{0:d}" SortExpression="RetireDate ASC" />
                <asp:BoundColumn DataField="Retailer" HeaderText="Retailer" ItemStyle-Width="10%" SortExpression="Retailer ASC" />
                <asp:BoundColumn DataField="StorageLocation" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="center" HeaderText="Box" ItemStyle-Width="3%" SortExpression="StorageLocation ASC" />
                <asp:TemplateColumn HeaderText="" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="Middle" HeaderStyle-HorizontalAlign="center" ItemStyle-Width="2%">
                    <ItemTemplate>
                        <asp:ImageButton src="Images/edit-alt-regular-24.png" ID="btneditset" alt="Edit" class="imagebutton" CommandName="Edit" runat="server" />
                    </ItemTemplate>
                </asp:TemplateColumn>
                <asp:TemplateColumn HeaderText="" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="Middle" HeaderStyle-HorizontalAlign="center" ItemStyle-Width="2%">
                    <ItemTemplate>
                        <asp:ImageButton src="Images/trash-regular-24.png" ID="btndeleteset" class="imagebutton" CommandName="Delete" runat="server"/>
                    </ItemTemplate>
                </asp:TemplateColumn>
            </Columns>
                <PagerStyle NextPageText="Next --&gt;" Font-Bold="True" PrevPageText="&amp;lt-- Prev" HorizontalAlign="Center" ForeColor="White" BackColor="Red" Mode="NumericPages" />
        </asp:datagrid>

如您所见,我有两个模板列,每个模板列都包含一个图像。一种用于删除,一种用于编辑。无论我如何尝试,我似乎都无法捕获这些图像按钮的点击事件。如果我用 ButtonColumn 替换其中之一,那么效果很好,但这意味着我无法使用图像。

在后面的代码中我设置了这些:

Sub dginventory_oneditcommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)

    lblfilters.Text = "edit"

End Sub


Sub dginventory_ondeletecommand(ByVal sender As Object, ByVal e As DataGridCommandEventArgs)

    lblfilters.Text = "delete"

End Sub

他们似乎都没有真正抓住任何东西。我也尝试过使用 onitemcommand ,它似乎又没有触发。我也尝试向两个图像按钮添加 onclick,但同样没有乐趣。

希望我已经描述得足够好。我使用 vb.net 作为后面的代码,以防不清楚。

希望如此......

asp.net vb.net events datagrid imagebutton
1个回答
0
投票

好的,当放入按钮、ImageButton,甚至是一行的组合框时,最简单的方法是什么?

忽略行命令方法,并为给定控件使用常规单击事件。

这里唯一的“技巧”是,因为控件是嵌套的(在转发器、Listview、GridView、DataGrid 等中),所以您没有给定控件的属性表,因此无法使用该属性控件上的工作表(或双击)以创建单击事件。

但是,您可以 100% 自由地通过直接输入标记来添加、使用和享受点击事件。 (英特尔感知仍然会帮助你)。

我还应该指出,DataGrid 可能是最古老的控件,事实上,您经常在工具箱中看不到 DataGrid。

所以,我建议大多数情况下使用 GridView。 (它们非常相似)。

如果您的数据“网格”有多个自定义控件,那么我建议使用 ListView,因为它对标记更加友好。不用担心,尽管 DataGrid 是一个较旧的控件,但使用它仍然可以。

那么,假设我们有一个像这样的简单 DataGrid:

(并注意 2 个图像按钮)。

所以,那么这个:

  <asp:DataGrid ID="GHotels" runat="server" AutoGenerateColumns="false"
     DataKeyField="ID" CssClass="table table-hover" Width="45%" >

      <Columns>
        <asp:BoundColumn HeaderText="First" DataField="FirstName" runat="server" />
        <asp:BoundColumn HeaderText="Last" DataField="LastName" runat="server" />
        <asp:BoundColumn HeaderText="City" DataField="City" runat="server" />
        <asp:BoundColumn HeaderText="HotelName" DataField="HotelName" runat="server" />
        <asp:BoundColumn HeaderText="Description" DataField="Description" runat="server" />

        <asp:TemplateColumn HeaderText="Edit">
            <ItemTemplate>
                <asp:ImageButton ID="cmdEdit" runat="server"
                    ImageUrl="~/Content/edit2.png" Width="48"
                    />
            </ItemTemplate>
        </asp:TemplateColumn>

        <asp:TemplateColumn HeaderText="Delete">
            <ItemTemplate>
                <asp:ImageButton ID="cmdDelete" runat="server"
                    ImageUrl="~/Content/trashcan1.png" width="48"
                    OnClick="cmdDelete_Click"

                    />

            </ItemTemplate>
        </asp:TemplateColumn>

      </Columns>
  </asp:DataGrid>

加载网格的代码如下所示:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If IsPostBack = False Then
        LoadGrid()
    End If


End Sub

Sub LoadGrid()

    Dim strSQL As String =
        "SELECT * FROM tblHotelsA
        ORDER BY HotelName"

    GHotels.DataSource = MyRst(strSQL)
    GHotels.DataBind()

End Sub

结果是这样的:

好的,那么我们给上面的图片删除按钮添加一个删除点击事件。

所以,从编辑看来是这样的:

因此,如上所示,我们可以并且可以轻松地为给定的控件使用标准单击事件(或其他事件)。这意味着几乎没有理由去打扰和尝试使用 row 命令。额外的好处是,我们为每个控件都有一个单独的点击事件,并且它们不会全部被一堆 case 语句混入一个事件中。

在后面的代码中,我们可以像这样获取行信息:

Protected Sub cmdDelete_Click(sender As Object, e As ImageClickEventArgs)

    Dim cmdDel As ImageButton = sender
    Dim gRow As DataGridItem = cmdDel.NamingContainer

    Dim PK As Integer = GHotels.DataKeys(gRow.ItemIndex)

    Dim strSQL As String =
        "DELETE FROM tblHotelsA WHERE ID = @ID"

    Dim cmdSQL As New SqlCommand(strSQL)
    cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = PK
    ' MyRstPE(cmdSQL)

    Debug.Print($"Row index click = {gRow.ItemIndex}")
    Debug.Print($"Database PK for row = {PK}")

End Sub

在上面,我展示了如何获取当前行(DataGridItem)。

上面我展示了如何获取数据库PK值。

在上面,我展示了如何获取行索引。

注意“命名”容器的使用。所有数据绑定控件都支持此功能,并返回当前行项目。

因此,当我单击给定的行按钮时,我会在输出/调试窗口中看到以下内容:

因此,您可以自由地对放置在 GridView、ListView、DataGrid 等中的控件使用常规单击事件。

上述建议还可以扩展到放入组合框或其他控件。也可以使用它们的事件,但您必须将事件设置直接“输入”到标记中,因为控件是嵌套的,因此没有可用的属性表。

为了完整起见,一遍又一遍地键入代码以使用提供的 SQL 提取数据表很快就会变得很累人,因此我在上面使用了一些辅助例程,并在整个应用程序中使用。

Public Function MyRst(strSQL As String, ByVal Optional strCon As String = "") As DataTable

    If strCon = "" Then
        strCon = My.Settings.TEST4
    End If

    Dim rstData As New DataTable
    Using conn As New SqlConnection(strCon)
        Using cmdSQL As New SqlCommand(strSQL, conn)
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
            rstData.TableName = strSQL
        End Using
    End Using
    Return rstData
End Function

Public Function MyRstP(cmdSQL As SqlCommand, ByVal Optional strCon As String = "") As DataTable

    If strCon = "" Then
        strCon = My.Settings.TEST4
    End If

    Dim rstData As New DataTable
    Using conn As New SqlConnection(strCon)
        Using (cmdSQL)
            cmdSQL.Connection = conn
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using

    Return rstData

End Function

Public Sub MyRstPE(cmdSQL As SqlCommand, ByVal Optional strCon As String = "")

    If strCon = "" Then
        strCon = My.Settings.TEST4
    End If

    Dim rstData As New DataTable
    Using conn As New SqlConnection(strCon)
        Using (cmdSQL)
            cmdSQL.Connection = conn
            conn.Open()
            cmdSQL.ExecuteNonQuery()
        End Using
    End Using

End Sub
© www.soinside.com 2019 - 2024. All rights reserved.