2013-02-28 96 views
2

您好,我正在設計一個自定義的.net Web控件,它繼承自aspx下拉列表。 這個想法是有一個下拉列表,將顯示年份值,直到今年。我希望能夠設置控件可以啓動的「StartYear」屬性,或者使用默認日期。我能夠創建這個控件,但它總是使用日期。看來我無法在後面的代碼中使用aspx代碼中的屬性設置。我的前端代碼是....簡單的自定義網頁控制

<customControls:YearDropDownList StartYear="2000" ID="ddlYear" runat="server"/> 

和後面的代碼是

using System; 
using System.ComponentModel; 
using System.Globalization; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

    namespace customControls { 
    [ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")] 
    [DefaultProperty("StartYear")] 
    public class YearDropDownList : DropDownList 
    { 
     public YearDropDownList() { 
      for (int i = Int32.Parse(StartYear); i <= DateTime.Now.Year; i++) 
      { 
       this.Items.Add(new ListItem(i.ToString(), i.ToString())); 
      } 
     } 
     public string StartYear { 
      get{ 
       String s = (String)ViewState["StartYear"]; 
       return ((s == null) ? "2009":s); 
      } 
      set{ 
       ViewState["StartYear"] = value; 
      } 
     } 
    } 
    } 

回答

1

需要重新生成時,該屬性設置像這樣的列表;

[ToolboxData("<{0}:YearDropDownList runat=\"server\" StartYear=\"[StartYear]\"></{0}:YearDropDownList>")] 
[DefaultProperty("StartYear")] 
public class YearDropDownList : DropDownList 
{ 
    protected override void OnInit(EventArgs e) 
    { 
     base.OnInit(e); 
     RegenerateList(); 
    } 
    public string StartYear 
    { 
     get 
     { 
      String s = (String)this.ViewState["StartYear"]; 
      return s ?? "2009"; 
     } 
     set 
     { 
      ViewState["StartYear"] = value; 
      RegenerateList(); 
     } 
    } 
    public void RegenerateList() 
    { 
     Items.Clear(); 
     for (int i = Int32.Parse(this.StartYear); i <= DateTime.Now.Year; i++) 
     { 
      this.Items.Add(new ListItem(i.ToString(), i.ToString())); 
     } 
    } 
} 

我已經測試並驗證上面的代碼,它最肯定工作。我注意到一件有趣的事情,那就是我可以在一段時間內重現你的問題,因爲屬性設定者沒有被擊中。我通過右鍵單擊該解決方案並單擊清理來解決此問題。解決方案清理完畢後,我再次右鍵單擊解決方案,但這次選擇了重建。這似乎解決了財產設置問題。

+0

如何從構造有什麼不同,然後編寫代碼構造調用一個函數? – JBone 2013-02-28 18:03:26

+0

@JBone它不是,而是在構造函數和屬性中兩次編寫代碼,我將它移入自己的方法中,並從兩個位置調用它。爲什麼在不需要的時候編寫代碼兩次? – DiskJunky 2013-02-28 18:05:57

+0

啊沒有看到它在setter,我會嘗試這 – JBone 2013-02-28 18:07:25

1

以我的想法,在構造函數中重新生成列表沒有任何意義。當控件被實例化時,ViewState可能不會被填充(儘管我不確定這一點),因此您將始終使用默認值。

這裏就是我想要做的:

[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")] 
[DefaultProperty("StartYear")] 
public class YearDropDownList : DropDownList 
{ 
    public string StartYear 
    { 
     get 
     { 
      String s = (String)ViewState["StartYear"]; 
      return ((s == null) ? "2009" : s); 
     } 
     set 
     { 
      ViewState["StartYear"] = value; 
      RegenerateList(); 
     } 
    } 

    // Defer regenerating the list until as late as possible  
    protected void OnPreRender(EventArgs e) 
    { 
     RegenerateList(); 
     base.OnPreRender(e); 
    } 

    public void RegenerateList() 
    { 
     // Remove any existing items. 
     this.Items.Clear(); 
     for (int i = Int32.Parse(StartYear); i <= DateTime.Now.Year; i++) 
     { 
      this.Items.Add(new ListItem(i.ToString(), i.ToString())); 
     } 
    } 
} 
+0

這是行不通的,問題是那個setter永遠不會被調用 – JBone 2013-02-28 18:32:55

+0

這個(setter不會被調用)是通過調試確定的嗎? – 2013-02-28 19:13:58

+0

是的,我已經添加了一個永遠不會被擊中的斷點 – JBone 2013-02-28 19:28:20