Reputation: 3203
Hello I am designing a custom .net web control that inherits from the aspx dropdownlist. The idea is to have a dropdownlist that will display year values up until the current year. I want to be able to set a "StartYear" property that the control can start from or else use a default date. I am able to create this control but it is always using the defult date. It seems I am unable to use the property setting in the aspx code in the code behind. My front end code is ....
<customControls:YearDropDownList StartYear="2000" ID="ddlYear" runat="server"/>
and the code behind is
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;
}
}
}
}
Upvotes: 2
Views: 1378
Reputation: 4971
you need to regenerate the list when the property is set like so;
[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()));
}
}
}
I have tested and verified the code above and it most definitely works. An interesting thing that I did notice was that I was able to reproduce your issue for a while in that the property setter was not being hit. I resolved this by right-clicking the solution and clicking Clean. After the solution was cleaned, I right-clicked on the solution again but this time selected Rebuild. That seemed to solve the property setter issue.
Upvotes: 1
Reputation: 13965
To my way of thinking, it doesn't make sense to regenerate the list in the constructor. At the time the control is instantiated, ViewState probably won't be populated yet (though I am not sure of this) and therefore you'll always get your default value being used.
Here's what I'd do:
[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()));
}
}
}
Upvotes: 1