2013-02-28 44 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