成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C# DropDownList的一個有意思的bug及解決

開發 后端
這里將就C#.Net 環境下Web開發中經常使用的C# DropDownList控件的SelectedIndex屬性進行了詳細的探討,發現了這一屬性在使用中存在的問題,并經過測試,提出了回避和解決的辦法。
C# DropDownList控件是C#.Net 控件面板Web Form下的一個控件,通過預先設定或動態數據綁定將其填入可供用戶選擇的數據,既方便了用戶操作,增強軟件的易用性,又能有效的規范數據輸入,成為軟件開發人員最常選擇的控件之一。

1.引言

信息和網絡的發展,使基于Web應用的系統越來越普及, VS.Net無疑是開發Web應用的系統的最合適的工具之一。但我們在長期的開發實踐中發現,C#.Net下DropDownList控件在使用過程中會遇到一些問題,它的SelectedIndex屬性存在一個讀寫缺陷,這個問題也一直困擾著其他的開發人員。因此,本文專門對DropDownList做了詳細的測試,來探求問題所在和解決辦法。

2.C# DropDownList控件介紹

DropDownList是C#.Net 控件面板Web Form下的一個控件,它的命名空間是System.Web.UI.WebControls.DropDownList。它是一個允許用戶從下拉列表中選擇一項的控件,通過在C# ropDownList 控件的開始和結束標記之間為每個項放置一個ListItem對象,可以指定希望顯示在C# DropDownList 控件中的項,也支持數據綁定。DropDownList的功能決定了它在日常開發中的實用性,在數據輸入控件中其使用率僅次于TextBox。通過預先設定或動態數據綁定將其填入可供用戶選擇的數據,既方便了用戶操作,增強軟件的易用性,又能有效的規范數據輸入,成為軟件開發人員最常選擇的控件之一。

3.關于SelectedIndex的有趣的問題

在長期的使用過程中我們發現,當在程序中動態將DropDownList列表中的某項選定,

或指定SelectedIndex為某一值時,會出現意想不到的錯誤。而使用斷點跟蹤調試方法或將SelectedIndex值讀取到某個變量進行測試,卻難以找到問題所在。

3.1 發現問題

假設有如下簡單代碼

  1. private void Page_Load(object sender, System.EventArgs e)   
  2.         {   
  3.             if (!IsPostBack)   
  4.             { //初始化DropDownList下拉列表   
  5.                 Init_FillList();   
  6.             }   
  7.         }   
  8.         private void btnOK_Click(object sender, System.EventArgs e)   
  9.         {   
  10.             string strID=txtContinentID.Text.Trim();   
  11.            //選擇指定項   
  12.             listContinent.Items.FindByValue(strID).Selected=true;   
  13.             Response.Write("OK!");   
  14.         }   
  15.         #region初始化下拉列表方法   
  16.         private void Init_FillList()   
  17.         {   //定義ListItem對象   
  18.             ListItem item;   
  19.             //清空列表   
  20.             listContinent.Items.Clear();   
  21.             //寫入列表   
  22.             listContinent.Items.Add(" ");   
  23.             item=new ListItem("亞洲","Asia");   
  24.             listContinent.Items.Add(item);   
  25.             item=new ListItem("歐洲","Euro");   
  26.             listContinent.Items.Add(item);   
  27.             item=new ListItem("美洲","Amer");   
  28.             listContinent.Items.Add(item);   
  29.         }   
  30.         #endregion  

把它放到一個簡單web頁面中直接運行,在輸入框中輸入大洲編號Asia,Euro ,Amer中的任一個,點擊btnOK按鈕鍵,看似沒有任何問題的代碼,報出了如下VS.Net著名的錯誤黃頁:(記為:錯誤A )

C# DropDownList 不能有多個項被選定。

說明: 執行當前 Web 請求期間,出現未處理的異常。請檢查堆棧跟蹤信息,以了解有關該錯誤以及代碼中導致錯誤的出處的詳細信息。異常詳細信息: System.Web.HttpException: DropDownList 不能有多個項被選定。

通過認真核查代碼并查詢聯機幫助,發現DropDownList的使用符合相關說明文檔的使用方法,沒有任何問題。

為了跟蹤查找錯誤的原因,在btnOK_Click()事件下的所有代碼外圍加try…catch保護進行調試,單步執行,發現一直執行到Response.Write("OK!")句,程序都沒有跳出,繼續向下,此時該事件已經執行完了,沒有錯誤,應該顯示出正常的web頁面,就在這時,上面的錯誤黃頁又出現了。調試無法找到錯誤所在,如何才能解決這個問題,難道是開發工具的原因,于是想到以下辦法.

3.2 問題暫時解決不能有多個項被選定,可能是因為DropDownList在選擇新項之前不能自動去除原來的選擇,即,不能有效的對已添入數據的列表進行初始化。于是在每次PostBack后將DropDownList的數據重新綁定刷新恢復到系統自己規定的默認值,然后再進行新的項的選擇,將Page_Load()事件下的代碼做如下調整 

  1. private void Page_Load(object sender, System.EventArgs e)   
  2. {   
  3. //去掉 if (!IsPostBack)每次都重寫數據   
  4. Init_FillList();   
  5.          } 

此時再運行程序,不再出現錯誤A,運行正常。但是web應用不同于局域網內系統的應用,它對程序執行效率要求更高,要盡量減少對服務器的訪問。如果一個頁面在每次刷新時都要重新訪問服務器初始化數據地話,會嚴重增加服務器的負擔。一旦數據量大或訪問的終端增多,將會使頁面顯示變的非常慢,客戶無法忍受。需要繼續尋求其他的解決辦法。

3.3 有趣的bug由于過去曾經長期從事Delphi下的應用系統的開發,對Combox控件的使用非常熟悉,由于他們的功能基本相同,推斷其使用方法應該也是有些相通的,于是對txtOK_Click()進行修改,得txtOK2_Click()事件:

  1. private void txtOK2_Click(object sender, System.EventArgs e)   
  2.         {      
  3.             string strID=txtContinentID.Text.Trim();   
  4.             this.listContinent.SelectedIndex=-1;//新加行   
  5.             listContinent.Items.FindByValue(strID).Selected=true;   
  6.             Response.Write("OK!");   
  7.          } 

運行程序,果然在加上IsPostBack判斷的情況下,程序仍能正常運行。然而這與msdn聯機幫助對DropDownList的使用說明是不符的。相關的屬性說明:“DropDownList.SelectedIndex 屬性,DropDownList控件中的選定項的索引。默認值為 0,該值選擇列表中的***項。備注 使用 SelectedIndex 屬性以編程方式指定或確定 DropDownList控件中的選定項的索引。DropDownList 控件中總是選擇一項。無法在列表中同時取消選擇所有項。注意 DropDownList 控件中的項的索引從零開始”。有趣的是不符合使用規定的程序沒有報任何錯誤,反而使程序運行正常。

為了查看SelectedIndex在運行時的實際值是0還是1或其他的值,再次跟蹤調試,此時發現了一個有趣的bug。把斷點設置到this.listContinent.SelectedIndex=-1行,當程序運行到這里時將鼠標移到SelectedIndex的位置,查看它的值,(或者通過開發環境下邊的變量查看器查看),發現此時的值是0,繼續向下運行,錯誤A又出現了。而同樣是調試狀態,單步執行代碼,只是不進行查看SelectedIndex的操作(通過變量查看器看也不可以),直到跟蹤完畢,程序運行也沒有問題。很明顯,這是C#.Net的一個bug。

3.4 換一種取值方式既然不能在調試時通過系統的返回值提示查看變量值,只能變通一下,通過自己定義變量來獲取SelectedIndex的值。于是對txtOK2_Click()進行修改,得txtOK3_Click()事件: 

  1.  private void btnOK3_Click(object sender, System.EventArgs e)   
  2.     {   
  3. //新加行 調試后知 i=0   
  4. int i= listContinent.SelectedIndex;   
  5.         string strID=txtContinentID.Text.Trim();   
  6.         this.listContinent.SelectedIndex=-1;   
  7. //新加行 調試后知 j=0   
  8.         int j=this.listContinent.SelectedIndex;   
  9.         listContinent.Items.FindByValue(strID).Selected=true;   
  10.         Response.Write("OK!");   
  11.         }  

運行程序,真正的問題出現了,不管在debug狀態還是非調試狀態,都是一樣的“DropDownList 不能有多個項被選定”錯誤。這說明SelectedIndex的值根本不能進行查看或讀取,這也進一步證明C#.Net中對SelectedIndex的讀取實現代碼有問題,存在不安全的判斷。

另外,經過此時的調試觀察i和j的返回值是一樣的結果,這個結果也和系統規定的SelectedIndex的默認值為 0一致。這證明了this.listContinent.SelectedIndex=-1這行代碼在txtOK2_Click()中是沒有起作用沒有用途的,然而加上該行代碼卻能解決問題,使程序正常運行。

3.5問題根源

通過反編譯工具和.NET源碼的幫助,找到了C#.Net中關于DropDownList的源碼實現,發現了這個問題存在的根源。以下是C#.Net中DropDownList的SelectedIndex屬性源碼實現:

  1. [WebCategory("Behavior"),DesignerSerializationVisibility
  2. (DesignerSerializationVisibility.Hidden),DefaultValue(0),
  3. WebSysDescription("DropDownList_SelectedIndex")]   
  4.  public override int SelectedIndex{      get      
  5. {            int num1 = base.SelectedIndex;            
  6. if ((num1 < 0) && (this.Items.Count > 0))           
  7. {                  
  8. this.Items[0].Selected = true;                  
  9. num1 = 0;            
  10. }            
  11. return num1;      }      
  12. set      
  13. {            
  14. base.SelectedIndex = value;        
  15. }} 

這段源碼實現表明,在取SelectedIndex時自動進行了判斷,只要有數據那么Selected的值就肯定大于等于0,所以我們在查看時發現設置成-1是無效的,它會自動改為0。另外它還做了另外一部操作this.Items[0].Selected = true,這個也就是直接導致Exception產生的原因(開發者只是想看看SelectedIndex它就把Item[0]的Selected值給改了...),所以在調試程序時要注意回避這個問題,我們只能通過修改代碼使程序運行正常,而無法改變 VS.NET的源碼實現。

程序測試界面,btnOK,btnOK2,btnOK3和列表數據綁定代碼的實現已在上面給出。

4.C# DropDownList結束語

經調試,在初始設置SelectedIndex=0的情況下同樣存在“錯誤A”的問題。而且若將3.3中SelectedIndex=-1改為SelectedIndex=0,此中情況程序不調試運行也會出現“錯誤A”。

在系統對效率要求不高,數據量小的情況下可以采用3.2的方法來回避這個問題,即每次加載頁面重新初始化DropDownList列表。也可采取3.3中將SelectedIndex設為-1的方法來改進這一問題,但此時不要對SelectedIndex=-1行進行單行調試。兩種方法在工程交付運行時都不會有任何因為SelectedIndex而引起的程序錯誤。

該文所有測試在Microsoft .NET Framework 1.1, C# .NET 2003 version 7.1,IE6.0 環境下編寫調試。

【編輯推薦】

  1. C# lock關鍵字敘述
  2. C#.Net FrameWork簡介
  3. C# new和override簡單描述
  4. C#值類型和引用類型淺談
  5. C#標識符簡單分析
責任編輯:彭凡 來源: CSDN
相關推薦

2020-12-12 13:50:16

云開發

2021-01-27 13:54:05

開發云原生工具

2018-06-24 16:39:28

Tomcat異常線程

2023-05-15 09:16:18

CSSCSS Mask

2024-05-20 01:10:00

Promise變量

2020-02-12 09:00:00

C#編程語言

2022-03-21 10:21:50

jQuery代碼模式

2020-03-10 14:59:16

oracle數據庫監聽異常

2021-03-25 06:12:55

SVG 濾鏡CSS

2012-05-22 10:12:59

jQuery

2023-11-21 21:59:50

c++接口

2022-06-15 07:21:47

鼠標指針交互效果CSS

2022-08-15 22:34:47

Overflow方向裁切

2024-03-18 08:14:07

SpringDAOAppConfig

2021-02-20 16:01:26

Github前端開發

2015-03-12 10:46:30

代碼代碼犯罪

2022-05-20 07:36:02

LiveTerm工具

2017-08-01 00:52:07

kafka大數據消息總線

2012-06-19 16:49:19

Web開發

2013-08-28 09:46:09

Debian LinuLinux發行版
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美精品一区在线 | 美美女高清毛片视频免费观看 | 久久婷婷国产麻豆91 | 精品网 | 久久精品国产99国产 | 无码一区二区三区视频 | 久久中文字幕电影 | 99色在线视频 | 国产亚洲网站 | 成人精品一区二区户外勾搭野战 | 久久久久国产 | 中文字幕成人在线 | 国产精品国产三级国产a | www.蜜桃av | 成人欧美一区二区三区 | 日韩欧美手机在线 | 久久一区二区三区四区五区 | 国产激情视频网站 | 久久久www成人免费无遮挡大片 | 免费一级黄 | 亚洲码欧美码一区二区三区 | 黄色免费在线观看 | 亚洲最大成人综合 | 午夜精品一区二区三区三上悠亚 | 3p视频在线观看 | 在线成人精品视频 | 国产精品视屏 | 日本久久一区 | 成人午夜网站 | 日韩午夜精品 | 在线播放第一页 | 99视频在线播放 | 一区二区三区四区av | 精品久久国产老人久久综合 | 不卡一二三区 | 久久久久无码国产精品一区 | 国产精品久久久久久av公交车 | 美女视频网站久久 | 精品国产91 | 91精品一区二区三区久久久久久 | 国产精品视频yy9299一区 |