zoukankan      html  css  js  c++  java
  • Enhancing Inserting Data through the DataGrid Footer, Part 2

    In Part 1 we looked at how to add a data-dependent DropDownList to the footer of a DataGrid. In this part we'll see how to add two DropDownLists, with the second DropDownList dependent upon the first.

    Adding a Second DropDownList to the DataGrid's Footer
    Now that we've seen how to add a single DropDownList to the DataGrid's footer, let's turn our attention at adding a second one that's dependent upon the first. That is, the values displayed in the second DropDownList depend on the value selected in the first DropDownList. We'll be building upon the code from the live demo we examined in Part 1.

    There are a couple of challenges in adding a second DropDownList:

    1. First, when the user selects a new option from the first DropDownList, the Web form needs to be posted back so that the second DropDownList can be populated with the appropriate list items for the newly selected item from the first DropDownList.
    2. Second, when the postback occurs, we must be able to determine what option was selected from the first DropDownList, and then bind the second DropDownList to the appropriate data. The main challenge here is in being able to reference the second DropDownList so its DataSource property can be set and its DataBind() method called.

    The first challenge can be solved with two additions to the code. First, we must specify that the first DropDownList, whenever it is changed, causes a postback. This is accomplished by setting the first DropDownList's AutoPostBack property to True. Next, we must create an event handler for the first DropDownList's SelectedIndexChanged event. This is the event that fires when the Web form is posted back after the first DropDownList has been changed. In this event's handler, we need to determine what option was selected, query the database for the appropriate data, and then bind this data to the second DropDownList.

    This leads us directly into the second challenge. In order to bind the data to the second DropDownList, we must be able to programmtically reference the second DropDownList so that it's DataSource property can be set and its DataBind() method called. While this might seem like it should be an easy task, it is a bit more tricky than it first appears. This task is tricky in part because the DataGrid does not make it easy to programmatically reference the footer. While the DataGrid provides the Items collection, this collection only contains those rows of the DataGrid that are actually bound to data.

    Typically, if one needs to programmatically access the footer they do so in the DataGrid's ItemDataBound event, which fires once for every row of the DataGrid, including the footer. However, this event only fires when the DataGrid's DataBind() method is called. Since the DataGrid is not bound after the user chooses a new list item from the first DropDownList, this route was not an option either.

    The solution I will present in this article comes from some clever developers at a software consulting company I consult with occassionally, Software Outfitters. The developers there realized that when the DataGrid footer is nothing more than an instance of the DataGridItem class. So, if they could programmatically reference this item instance, they could easily snag the second DropDownList using the FindControl() method. The way they accessed the DataGridItem representing the footer is as follows: in the first DropDownList's SelectedIndexChanged event handler, they could reference the DropDownList causing the event to fire (via the sender parameter to the event handler). With this control, they could reference the TableCell the DropDownList appears in by using the DropDownList's Parent property. (The Parent property returns a control's parent control.) Using the Parent property again, they could get the DataGridItem that contained the TableCell that contained the first DropDownList. With a reference to the DataGridItem they could use the FindControl() method to get the second DropDownList.

    The solution to these two challenges can be seen in the following code example and live demo. When examining the code, realize that the ASPFAQs.com data model does not have any sort of natural two-level hierarchy that would make two dependent DropDownLists sensible. However, if the data model was adjusted so that FAQs could contain both a category and subcategory, the two DropDownList example would be more realistic. Instead, the code sample below is a bit contrived. The first DropDownList lists the various FAQ categories (as it did in the first live demo. The second DropDownList displays all of the FAQs for the FAQ category selected from the first DropDownList. That is, if you change the category in the first DropDownList, the page is posted back and the second DropDownList lists the FAQs for the newly selected category.

    <% @Import Namespace="System.Data" %>
                <% @Import Namespace="System.Data.SqlClient" %>
                <script language="vb" runat="server">
                'Create a connection
                Dim myConnection as New _
                SqlConnection(ConfigurationSettings.AppSettings("connectionString"))
                Dim ddlDataSet as DataSet = New DataSet()
                Sub Page_Load(sender as Object, e as EventArgs)
                If Not Page.IsPostBack then
                BindData()
                End If
                End Sub
                Sub BindData()
                'Code removed for brevity
                End Sub
                Function GetCategories() as DataSet
                'Code removed for brevity
                End Function
                Function GetFAQsByCategory(catID as Integer) as DataTable
                'Populate the ddlDataSet
                Dim strSQLDDL as String
                If catID < 0 then
                strSQLDDL = "SELECT FAQID, Description FROM tblFAQ " & _
                "WHERE FAQCategoryID = " & _
                "(SELECT TOP 1 FAQCategoryID FROM tblFAQCategory " & _
                "ORDER BY Name) " & _
                "ORDER BY Description"
                Else
                strSQLDDL = "SELECT FAQID, Description FROM tblFAQ " & _
                "WHERE FAQCategoryID = " & catID
                End If
                Dim myDataAdapter as SqlDataAdapter = New _
                SqlDataAdapter(strSQLDDL, myConnection)
                myDataAdapter.Fill(ddlDataSet, "FAQs")
                Return ddlDataSet.Tables("FAQs")
                End Function
                Function GetSelectedIndex(CID as String) as Integer
                Dim iLoop as Integer
                Dim dt as DataTable = ddlDataSet.Tables("Categories")
                For iLoop = 0 to dt.Rows.Count - 1
                If Int32.Parse(CID) = Int32.Parse(dt.Rows(iLoop)("FAQCategoryID")) then
                Return iLoop
                End If
                Next iLoop
                End Function
                Sub dgPopFAQs_Insert(sender as Object, e As DataGridCommandEventArgs)
                If e.CommandName = "Insert" then
                Dim lstFAQInsert as DropDownList = e.Item.FindControl("lstFAQsByCategory")
                Dim lstCatInsert as DropDownList = e.Item.FindControl("lstCategoriesInsert")
                Response.Write("<b>The Insert Command has no effect on this live demo</b><br />")
                Response.Write("<b>The data you would have inserted, though, was:<ul>")
                Response.Write("<li>" & lstCatInsert.SelectedItem.Text & "</li>")
                Response.Write("<li>" & lstFAQInsert.SelectedItem.Text & "</li></ul></b>")
                End If
                End Sub
                Sub LoadSecondDDL(sender as Object, e as EventArgs)
                'Reference the FAQCategoriesID DropDownList
                Dim categories as DropDownList = sender
                'Get the FAQ DropDownList
                Dim dgFooter as DataGridItem = categories.Parent.Parent
                Dim FAQDDL as DropDownList = dgFooter.FindControl("lstFAQsByCategory")
                'Get the value of FAQCategoryID
                Dim FAQCatID as Integer = categories.SelectedItem.Value
                'Get the list of FAQs for the specific category
                FAQDDL.DataSource = GetFAQsByCategory(FAQCatID)
                FAQDDL.DataBind()
                End Sub
                </script>
                <form runat="server">
                <asp:datagrid id="dgPopularFAQs" runat="server"
                AutoGenerateColumns="False"
                OnItemCommand="dgPopFAQs_Insert"
                ShowFooter="True"
                ...>
                <Columns>
                <asp:TemplateColumn ItemStyle-Width="10%"
                ItemStyle-HorizontalAlign="Center" HeaderText="FAQ ID"
                FooterStyle-HorizontalAlign="Center">
                <ItemTemplate>
                <%# Container.DataItem("FAQID") %>
                </ItemTemplate>
                <FooterTemplate>
                <asp:Button Text="Add" CommandName="Insert" runat="server" />
                </FooterTemplate>
                </asp:TemplateColumn>
                <asp:TemplateColumn HeaderText="Category">
                <ItemTemplate>
                <%# Container.DataItem("CategoryName") %>
                </ItemTemplate>
                <FooterTemplate>
                <asp:DropDownList runat="server" id="lstCategoriesInsert"
                DataValueField="FAQCategoryID"  DataTextField="Name"
                DataSource='<%# GetCategories() %>'
                AutoPostBack="True"
                OnSelectedIndexChanged="LoadSecondDDL" />
                </FooterTemplate>
                </asp:TemplateColumn>
                <asp:TemplateColumn HeaderText="FAQ Question">
                <ItemTemplate>
                <%# Container.DataItem("Description") %>
                </ItemTemplate>
                <FooterTemplate>
                <asp:DropDownList runat="server" id="lstFAQsByCategory"
                DataValueField="FAQID"  DataTextField="Description"
                DataSource='<%# GetFAQsByCategory(-1) %>' />
                </FooterTemplate>
                </asp:TemplateColumn>
                </Columns>
                </asp:datagrid>
                </form>
                

    Conclusion
    In this article we examined how to extend John Sanborn's earlier article on inserting new records using the DataGrid's footer. Specifically, we saw how to add a data-dependent DropDownList Web control to one of the column's of the footer, as well as how to add two DropDownLists, where one was dependent upon the selected value in the other.

    Happy Programming!

  • 相关阅读:
    工具类-ApplicationContextUtil
    银行联行号-全国地区码
    银行联行号-银行编码(联行号前3位)
    前端防止 JS 调试技巧
    Vue基础框架
    关于5G手机使用4G套餐扫盲
    nginx高级-前端必会
    懒人npm运行和打包命令
    关于虚拟专用网络的一些经验
    JS加密解密
  • 原文地址:https://www.cnblogs.com/hhq80/p/662205.html
Copyright © 2011-2022 走看看