2014年9月18日 星期四

[ASP.NET]GridView中的控制項修改其他行控制項Part2

上一篇研究如何知道目前是哪一列的的控制項被觸發

好讓我們可以去修改同一列的內容

雖然提出了一個方式

但可以解決這問題的方式果然不只一種

論壇上topcat跟MIS2000提出用NamingContainer來取得我在哪個控制項中(就是GridViewRow)

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
    DropDownList ddl = sender as DropDownList;
    GridViewRow gv = ddl.NamingContainer as GridViewRow;
    Label lb = gv.FindControl("Label1") as Label;
    lb.Text = ddl.SelectedValue;
}


不過讓我覺得神奇是Allen提出來的方式

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
    var ddl = sender as DropDownList;
    var lb = ddl.FindControl("Label1") as Label;
    lb.Text = ddl.SelectedValue;
}

重點在var lb = ddl.FindControl("Label1") as Label;這段

我本來以為FindControl是專門用來找某個控制項中的子控制項(剛好跟NamingContainer相反)

但居然可以用同一階的控制項找到其他控制項

這可就神奇了~

因為依照MSDN上的解釋FindControl的功能「以指定的id去搜尋當前容器"內"的伺服器控制項。」

既然是內沒想到連隔壁的都可以找到

看來我對FindControl特性還不夠熟

有好好研究的必要!

參考文獻
使用 NamingContainer 屬性決定控制項的命名容器
Control.NamingContainer 屬性
HOW TO:存取 Web 伺服器控制項命名空間的成員
Control.FindControl 方法 (String)
GridView中取得目前使用的控制項所在的列

2014年9月17日 星期三

[ASP.NET]GridView中的控制項修改其他行控制項

在GridView中你可能有一行有DropDownList

你希望選擇這一行的DropDownList可以讓另外一行的Label帶出資料

像是選擇幣別然後同一列的其他行帶出匯率之類的

這個功能在SelectedIndexChanged就能辦到

但會有個問題

我怎麼知道是哪一列的DropDownList被異動?

如果我不知道是哪個DropDownList被異動

我又怎麼知道要去修改哪一列的內容

這個問題解法似乎很多

目前我只想到這種解法

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("No", typeof(string)));

            for (int i = 0; i < 5; i++)
            {
                DataRow dr = dt.NewRow();
                dr["No"] = i.ToString();
                dt.Rows.Add(dr);
            }
            GridView1.DataSource = dt;
            GridView1.DataBind();
        }
    }
    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        DropDownList ddl = sender as DropDownList;
        int index = Convert.ToInt32(ddl.Attributes["index"]);
        Label txt = GridView1.Rows[index].FindControl("Label1") as Label;
        txt.Text = ddl.SelectedValue;
    }
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            DropDownList ddl = e.Row.FindControl("DropDownList1") as DropDownList;
            ddl.Attributes.Add("index", e.Row.RowIndex.ToString());
        }
    }

簡單說就是利用每個控制項都有的Attributes

用Attributes取個編號到時候你再取出當下這個DropDownList的編號就可以知道是那一列了

如果是Button可以用RowCommand的事件知道是哪個按鈕被按

印象中應該還有其他解決方式

有研究出來再來分享吧~