Контрол мега простой, текст бокс и дропдаун минуты/часы/дни/недели. Возвращает и получает TimeSpan, используется для two-way binding. Он работает, но я подозреваю, что какие-нить гайдлайны и прочие заветы Эспозито я нарушил. Так ли это? Особенно смущает меня RegisterRequiresPostBack
using System;
using System.Collections.Specialized;
using System.Web.UI;
public partial class TimeSpanControl : UserControl, IValidator, IPostBackDataHandler
{
public enum Period
{
Minutes, Hours, Days, Weeks
}
public TimeSpan? Duration
{
get { return ViewState["Duration"] as TimeSpan?; }
set { ViewState["Duration"] = value; }
}
public Period? PeriodType
{
get { return ViewState["PeriodType"] as Period?; }
set { ViewState["PeriodType"] = value; }
}
public int? TotalHours
{
get { return Duration == null ? null : (int?) Duration.Value.TotalHours; }
set
{
if(value == null)
{
Duration = null;
}
else
{
Duration = new TimeSpan(value.Value, 0,0);
}
}
}
public int? TotalMinutes
{
get { return Duration == null ? null : (int?)Duration.Value.TotalMinutes; }
set
{
if (value == null)
{
Duration = null;
}
else
{
Duration = new TimeSpan(0, value.Value, 0);
}
}
}
public int? TotalDays
{
get { return Duration == null ? null : (int?)Duration.Value.TotalDays; }
set
{
if (value == null)
{
Duration = null;
}
else
{
Duration = new TimeSpan(value.Value, 0, 0, 0);
}
}
}
private void InitControls() {
Period period = PeriodType ?? GetBestPeriod();
switch (period)
{
case Period.Minutes:
DurationText.Text = Duration == null ? "" : Duration.Value.TotalMinutes.ToString();
PeriodTypeList.SelectedValue = Period.Minutes.ToString();
break;
case Period.Hours:
DurationText.Text = Duration == null ? "" : Duration.Value.TotalHours.ToString();
PeriodTypeList.SelectedValue = Period.Hours.ToString();
break;
case Period.Days:
DurationText.Text = Duration == null ? "" : Duration.Value.TotalDays.ToString();
PeriodTypeList.SelectedValue = Period.Days.ToString();
break;
case Period.Weeks:
DurationText.Text = Duration == null ? "" : (Duration.Value.TotalDays / 7).ToString();
PeriodTypeList.SelectedValue = Period.Weeks.ToString();
break;
}
}
private void ParseDuration()
{
Period period;
Enum.TryParse(PeriodTypeList.SelectedValue, out period);
PeriodType = period;
int duration = Int32.Parse(DurationText.Text);
switch (period)
{
case Period.Minutes:
Duration = new TimeSpan(0,duration, 0);
break;
case Period.Hours:
Duration = new TimeSpan(duration, 0, 0);
break;
case Period.Days:
Duration = new TimeSpan(duration, 0, 0, 0);
break;
case Period.Weeks:
Duration = new TimeSpan(duration * 7 , 0, 0, 0);
break;
}
}
protected override void OnPreRender(EventArgs e)
{
Page.RegisterRequiresPostBack(this);
base.OnPreRender(e);
if(!IsPostBack)
{
InitControls();
}
}
private Period GetBestPeriod()
{
if(Duration == null)
{
return Period.Hours;
}
int minutes = (int) Duration.Value.TotalMinutes;
if(minutes % 60 != 0)
{
return Period.Minutes;
}
if(minutes % (60 * 24) != 0)
{
return Period.Hours;
}
return minutes % (60 * 24 * 7) != 0 ? Period.Days : Period.Weeks;
}
public void Validate()
{
DurationValidator.Validate();
}
public bool IsValid
{
get { return DurationValidator.IsValid; }
set { DurationValidator.IsValid = value; }
}
public string ErrorMessage
{
get { return DurationValidator.ErrorMessage; }
set { DurationValidator.ErrorMessage = value; }
}
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
ParseDuration();
return true;
}
public void RaisePostDataChangedEvent()
{
}
}