[ASP.NET][問答集] 連動DropDownList With Repeater

  • 6765
  • 0
  • 2011-11-11

[問答集] 連動DropDownList With Repeater

這是在論壇裡看到的一則發問,其實原發問者沒有詳細的說明原因,只問了

dropdownlist要連動也要預選,不過仔細看了一下發問者貼上來的Code,

發現其DropDownList 其實是包在Repeater裡的,也就是說真正的問題應該

『在Repeater裡如何達到連動式選單』

 

這個問題大致有幾個地方要了解一下

(1)首先要知道Repeater這類的元件一定會有個ItemDataBound的部份,雖然名稱

可能不盡相同,不過含義是差不多,也就是把資料項目一筆筆給Render出來,例如:

Repeater 的 ItemDataBound  / GridView 的 RowDataBound / DataList 的 ItemDataBound

 

(2)要如何取得同一筆資料中彼此連動的物件,也就是要知道所謂的FindControl,

在此就不多做解釋,有關FindControl可參考之前小弟的另一篇文章

 

(3)因為要連動,所以觸發連動的元件一定會有其引發連動的事件,以原發問者的案例會是

DropDownList 的SelectedIndexChanged事件

 

瞭解這幾個點之後,大致上應該就沒什麼太大的問題,這裡就初步做了個範例

( 此範例沒有考慮太多條件判斷,實際應用時該判斷的部份請自行考慮囉!)

 

範例:在Repeater裡提供三個DropDownList ,分別進行國家/地區/郵地區號的連動選擇

 

(1)畫面上我們拉了一個Repeater控制項,並且在ItemTemplate裡設計好所需的版面

DropDownList控制項

image

 

(2)接著撰寫一個獨立的Method進行在Repeater 的資料繫結


protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
        DataLoad();
}

private void DataLoad()
{
    using (SqlConnection conn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["DBconnStr"].ToString()))
    {
        conn.Open();
        using (SqlCommand command = new SqlCommand())
        {
            command.Connection = conn;
            command.CommandText = "select top 10 id from basecode";
            IDataReader idr = command.ExecuteReader();
            this.Repeater1.DataSource = idr;
            this.Repeater1.DataBind();
        }
        conn.Close();
    }
}

 

(3)接著如前面我們所分析的,在Repeater 的 ItemDataBound ,我們要針對DropDownList

控制項進行資料繫結及預設值,並且三個DropDownList 有連動間的關係,在這個部份選擇

撰寫三個獨立的Method來進行

a.國別的DropDownList ,具有二個參數,分別DropDownList 控制項及defvalue


private void BindCountry(DropDownList country,string defvalue)
{ 
    using (SqlConnection conn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["DBconnStr"].ToString()))
    {
        conn.Open();
        using (SqlCommand command = new SqlCommand())
        {
            command.Connection = conn;
            command.CommandText = "select id,name from country order by code";
            IDataReader idr = command.ExecuteReader();
            country.DataSource = idr;
            country.DataTextField = "name";
            country.DataValueField = "id";
            country.DataBind();
        }
        conn.Close();
    }
    if (!string.IsNullOrEmpty(defvalue))
        country.SelectedValue = defvalue.ToLower();

}

b.地區別的DropDownList ,具有三個參數,分別DropDownList 控制項及國別的Value及defvalue


private void BindCity(DropDownList city,Guid countryval, string defvalue)
{
    using (SqlConnection conn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["DBconnStr"].ToString()))
    {
        conn.Open();
        using (SqlCommand command = new SqlCommand())
        {
            command.Connection = conn;
            command.CommandText = "select id,name from city  where countryid=@countryid order by name";
            command.Parameters.Add("@countryid", DbType.Guid).Value = countryval;
            IDataReader idr = command.ExecuteReader();
            city.DataSource = idr;
            city.DataTextField = "name";
            city.DataValueField = "id";
            city.DataBind();
        }
        conn.Close();
    }
    if (!string.IsNullOrEmpty(defvalue))
        city.SelectedValue = defvalue.ToLower();
}

c.郵地區號的DropDownList ,具有三個參數,分別DropDownList 控制項及地區別的Value及defvalue


private void BindZip(DropDownList zip, Guid cityval, string defvalue)
{
    using (SqlConnection conn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["DBconnStr"].ToString()))
    {
        conn.Open();
        using (SqlCommand command = new SqlCommand())
        {
            command.Connection = conn;
            command.CommandText = "select id,name from zip  where cityid=@cityid order by code";
            command.Parameters.Add("@cityid", DbType.Guid).Value = cityval;
            IDataReader idr = command.ExecuteReader();
            zip.DataSource = idr;
            zip.DataTextField = "name";
            zip.DataValueField = "id";
            zip.DataBind();
        }
        conn.Close();
    }
    if (!string.IsNullOrEmpty(defvalue))
        zip.SelectedValue = defvalue.ToLower();
}

d.在Repeater 的 ItemDataBound ,進行DropDownList 各自的DataBind動作及Set defvalue

,這裡的程式碼就比較簡潔了,因為已經把DropDownList 各自的DataBind的部份拉出去額外

撰寫,所在這裡的重點就是要知道如何FindControl,然後進行各自DataBind的呼叫,另外由於

第2,3個DropDownList 需要取得前一個的Value,因此在BindCity & BindZip額外提供了前項

的SelectValue值的參數傳入


protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    DropDownList country =(DropDownList) e.Item.FindControl("Country");
    DropDownList city = (DropDownList)e.Item.FindControl("City");
    DropDownList zip = (DropDownList)e.Item.FindControl("Zip");
    BindCountry(country, "3B324BC4-8E29-4158-9A4B-EB3A3038ABDE");
    BindCity(city, new Guid(country.SelectedValue), "4C56DE70-03C0-4026-A37C-6970101F2809");
    BindZip(zip, new Guid(city.SelectedValue), "20D25662-D508-40C4-BDD4-633750803BEB");
}

 

(4)此外由於選項間必須要有連動的作業,因此在DropDownList的SelectedIndexChanged裡

,也須進行連動式的資料繫結,這裡的重點也是要知道如何Find到同一筆資料中的要連動的相

關控制項,所以我們利用NamingContainer來Find相關的Control


protected void Country_SelectedIndexChanged(object sender, EventArgs e)
{
    DropDownList country = ((DropDownList)sender);
    DropDownList city = (DropDownList)country.NamingContainer.FindControl("City"); //利用NamingContainer來Find相關的Control
    DropDownList zip = (DropDownList)country.NamingContainer.FindControl("zip");//利用NamingContainer來Find相關的Control

    BindCity(city, new Guid(country.SelectedValue),"");
    BindZip(zip, new Guid(city.SelectedValue), "");
}

 


protected void City_SelectedIndexChanged(object sender, EventArgs e)
{
    DropDownList city = ((DropDownList)sender);
    DropDownList zip = (DropDownList)city.NamingContainer.FindControl("zip");//利用NamingContainer來Find相關的Control

    BindZip(zip, new Guid(city.SelectedValue), "");
}

 

(5)結果

image

 

以上就是這個簡單範例的程式碼,當然這只是其中一種做法,此外這個範例中並未做太多的條件

判斷或是效能等等的考量,實務運用上還是要多加一些嚴謹的判斷及控制

 

重點還在於當理解原理之後,不管是用Repeater 或是GridView或是DataList,應該都是可以迎刃而解囉

 

 

 

 

 

 

若本文對您有所幫助,歡迎轉貼,但請在加註【轉貼】及來源出處,並在附上本篇的超連結,感恩您的配合囉。

By No.18