[ASP.NET 自訂控制項]DropDownList唯讀時改用TextBox/Label顯示

  • 26278
  • 0

[ASP.NET 自訂控制項]DropDownList唯讀時改用TextBox/Label顯示

緣由:

案子上SA希望DropDownList在頁面唯讀時,可以不給User選取,

但是設定Enabled=false,會導致畫面上的<select>字是灰色的,SA希望字不是灰色的,

如果做不到也可以乾脆用textbox或label來顯示唯讀的資訊。

讓該控制項的資訊,如同word的內文呈現,可以跟前後文直接串接在一起。

 

Enabled設定成false時,Render到頁面上會將disabled屬性設成唯讀。

用了一下CSS去改字體顏色,似乎是沒啥作用。(有其他大大可以提供解法的話,再麻煩指導一下)

 

CSS這條路try不出來之後,其實有兩種解法,

解法1:利用javascript去記錄目前<Select>的selectedindex,

接著判斷如果<select>.disable=true,就將<select>.disable改成false,

這樣一來,字就不會灰灰的,但是要怎麼控制唯讀呢?

很簡單,把<Select>裡面的items全部remove掉,只保留剛剛選取的item,

只剩下一個item,自然就沒得選了。


解法2:由於對Custom Control還蠻熟的,讓開發成員最無腦的方式,就是直接把DropDownList改掉。

這邊示範的是,覆寫DropDownList的Render()事件,判斷若DropDownList的Enabled為唯讀,則Render成textbox,

自動根據內文的多寡控制textbox的長度。

好處是,仍然保留DropDownList的viewstate,對開發人員來說,它就是一個長的像textbox的DropDownList。對寫server端的CODE來說,完全沒有差異。

甚至還可以讀取到selectedindex和selectedvalue。

 


程式碼如下:


using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Joey
{
    public class JoeyDropDownList : DropDownList
    {
        int _ReadOnlyWidth = 0;
        /// <summary>
        /// Gets or sets the width of the Readonly.
        /// </summary>
        /// <value>The width of the readonly.</value>
        public int ReadOnlyWidth
        {
            get { return _ReadOnlyWidth; }
            set { _ReadOnlyWidth = value; }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (this.Enabled)
            { base.Render(writer); }
            else
            {
                if (this.ReadOnlyWidth == 0)
                { this.ReadOnlyWidth = 13; }
                int textlength = this.SelectedItem.Text.Length;
                writer.AddAttribute("value", this.SelectedItem.Text);
                writer.AddAttribute("type", "text");
                writer.AddAttribute("readonly", "readonly");
                writer.AddAttribute("style", "width:" + Convert.ToString(textlength * this.ReadOnlyWidth) + "px;" + "border:solid 0px;" + "text-align:center;");
                writer.RenderBeginTag("input");
                writer.RenderEndTag();
            }            
        }

    }
}

 

 

 

 

 

 

 

Sample頁面aspx



<%@ Register Assembly="Joey" Namespace="Joey" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>未命名頁面</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <cc1:joeydropdownlist id="JoeyDropDownList1" runat="server">
            <asp:ListItem Value="14">Ace</asp:ListItem>
            <asp:ListItem Value="13">King</asp:ListItem>
            <asp:ListItem Value="12">Queen</asp:ListItem>
            <asp:ListItem Value="11">Jack</asp:ListItem>
            <asp:ListItem Value="JoeyTesting">長一點的選項用來測試自動寬度</asp:ListItem>
        </cc1:joeydropdownlist>
        <asp:Button ID="Button1" runat="server" Text="不唯讀" />
        <asp:Button ID="Button2" runat="server" Text="唯讀" />
        DropDownlist的值<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        DropDownlist的text<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
    </div>
    </form>
</body>
</html>

 

 

 

 

 

 

Sample頁面aspx.vb


Partial Class TestDropDownList
    Inherits System.Web.UI.Page
    Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click        
        Me.JoeyDropDownList1.Enabled = False
        Me.TextBox1.Text = Me.JoeyDropDownList1.SelectedValue
        Me.TextBox2.Text = Me.JoeyDropDownList1.SelectedItem.Text
    End Sub

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click        
        Me.JoeyDropDownList1.Enabled = True
        Me.TextBox1.Text = Me.JoeyDropDownList1.SelectedValue
        Me.TextBox2.Text = Me.JoeyDropDownList1.SelectedItem.Text
    End Sub
End Class

 

 

 

 

 

 

 


畫面demo:

1.一開始不唯讀的狀態,選取Queen

1

2.點了唯讀後,Queen變成文字

2

3.點了不唯讀後,選”長一點的選項用來測試自動寬度”,來測試中文

3

4.點了唯讀後,”長一點的選項用來測試自動寬度”變成文字

4

PS:寬度的部分,額外開了一個屬性給外面設定,若不設定,預設一個字為13px,其實13是給中文字使用,英文數字應該是7px。

想要改良的人可以自行判斷SelectedItem.Text有幾個英文數字,有幾個中文字,再去調整自動寬度。

PS2:請注意最後Render的tag是input,type為text,如果會被CSS或版面影響,請自行調整。(例如擺在最後面會不會長度太長沒自動斷行之類的…)


感謝Williams提供ASP.NET forum上的另外一種解答:http://forums.asp.net/p/1021814/1384091.aspx

forum上的code如果要放在自訂控制項裡面,就是把Render()覆寫成下面的code。

        protected override void Render(HtmlTextWriter writer)
        {
            if (!this.Enabled)
            {
                this.Enabled = true;
                foreach (ListItem i in this.Items)
                {
                    if (i.Selected != true)
                    { i.Enabled = false; }

                }


                base.Render(writer);
                this.Enabled = false;
                
            }

            else
            { base.Render(writer); }                        
        }

Source Code下載:(把兩種作法都包進去的class檔):  JoeyDropDownList.rar


blog 與課程更新內容,請前往新站位置:http://tdd.best/