Dynamisk tilføjelse af kontroller i compositecontrol
Jeg har en CompositeControl hvor jeg tilføjer en bunke DropDownList og knapper. Alle kontroller genereres på ny ved hvert postback med de samme ID via en Controls.Clear. Problem er hvis jeg i button click event ikke gør noget, skal jeg klikke to gange på knap før man ser de nyeste tilføjet kontroller. Kalder jeg CreateChildControls i click handler så ser jeg korrekt de nye kontroller, men så mister jeg ViewState på mine dropdowns. Hvad er den rigtige apporach til dette (se evt kode nedenstående):using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using Test.Common;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web;
namespace Test.Controls
{
public class OpenHour : CompositeControl, INamingContainer, IPostBackDataHandler
{
public OpenHour()
{
// EnsureChildControls();
}
//protected override void OnInit(EventArgs e)
//{
// base.OnInit(e);
// this.EnsureChildControls();
//}
protected override void CreateChildControls()
{
if (ChildControlsCreated)
return;
base.Controls.Clear();
CreateControlHierarchy();
ChildControlsCreated = true;
}
void CreateControlHierarchy()
{
if (Items == null)
{
InitItems();
}
Table tblOuter = new Table();
foreach (Weekday day in Enum.GetValues(typeof(Weekday)))
{
var intervals = Items.Where(p => p.DayOfWeek == day).First();
AddOpenHourIntervalRow(tblOuter, intervals, day);
}
this.Controls.Add(tblOuter);
}
void AddOpenHourIntervalRow(Table table, OpenHourIntervalCollection itemsForCurrentDay, Weekday day)
{
bool firstItem = true;
foreach (OpenHourInterval interval in itemsForCurrentDay)
{
List<BaseCell> row = new List<BaseCell>();
string dayText = day.ToString();
TimePicker timePickerStart = new TimePicker();
timePickerStart.ID = "timePickerStart" + interval.Id.ToString();
TimePicker timePickerEnd = new TimePicker();
timePickerEnd.ID = "timePickerEnd" + interval.Id.ToString();
if (firstItem)
row.Add(new TextCell(dayText));
else
row.Add(new TextCell(string.Empty));
row.Add(new ControlCell(timePickerStart));
row.Add(new TextCell("Til"));
row.Add(new ControlCell(timePickerEnd));
interval.TimePickerStartId = timePickerStart.ID;
interval.TimePickerEndId = timePickerEnd.ID;
HtmlGenericControl spanButtons = new HtmlGenericControl("span");
if (firstItem)
{
ImageButtonOpenHour imgbtnAdd = GetImageButton("ImageButtonWeekdayAdd", "/Images/16x16/add.png", day, interval.Id, new ImageClickEventHandler(imgbtnAdd_Click));
ImageButtonOpenHour imgbtnLock = GetImageButton("ImageButtonWeekdayLock", "/Images/16x16/lock.png", day, interval.Id, new ImageClickEventHandler(imgbtnLock_Click));
ImageButtonOpenHour imgbtnOpen = GetImageButton("ImageButtonWeekdayOpen", "/Images/16x16/key.png", day, interval.Id, new ImageClickEventHandler(imgbtnOpen_Click));
spanButtons.Controls.Add(imgbtnAdd);
spanButtons.Controls.Add(imgbtnLock);
spanButtons.Controls.Add(imgbtnOpen);
if (itemsForCurrentDay.Enabled)
{
imgbtnLock.Visible = true;
imgbtnAdd.Visible = true;
imgbtnOpen.Visible = false;
}
else
{
imgbtnLock.Visible = false;
imgbtnAdd.Visible = false;
imgbtnOpen.Visible = true;
}
}
else
{
ImageButtonOpenHour imgbtnDelete = GetImageButton("ImageButtonWeekdayDelete" + interval.Id.ToString(), "/Images/16x16/delete.png", day, interval.Id, new ImageClickEventHandler(imgbtnDelete_Click));
spanButtons.Controls.Add(imgbtnDelete);
}
row.Add(new ControlCell(spanButtons));
table.AddRow(row.ToArray());
firstItem = false;
}
}
ImageButtonOpenHour GetImageButton(string id, string url, Weekday day, Guid intervalId, ImageClickEventHandler clickHandler)
{
ImageButtonOpenHour btn = new ImageButtonOpenHour();
btn.ID = id + "_" + day.ToString();
btn.ImageUrl = url;
btn.Weekday = day;
btn.IntervalId = intervalId;
btn.Click += clickHandler;
return btn;
}
void imgbtnDelete_Click(object sender, ImageClickEventArgs e)
{
ImageButtonOpenHour btn = sender as ImageButtonOpenHour;
var intervals = Items.Where(p => p.DayOfWeek == btn.Weekday).First();
var interval = intervals.Find(p => p.Id == btn.IntervalId);
intervals.Remove(interval);
CreateChildControls();
}
void imgbtnOpen_Click(object sender, ImageClickEventArgs e)
{
ImageButtonOpenHour btn = sender as ImageButtonOpenHour;
var intervals = Items.Where(p => p.DayOfWeek == btn.Weekday).First();
intervals.Enabled = true;
CreateChildControls();
}
void imgbtnLock_Click(object sender, ImageClickEventArgs e)
{
ImageButtonOpenHour btn = sender as ImageButtonOpenHour;
var intervals = Items.Where(p => p.DayOfWeek == btn.Weekday).First();
intervals.Enabled = false;
CreateChildControls();
}
void imgbtnAdd_Click(object sender, ImageClickEventArgs e)
{
ImageButtonOpenHour btn = sender as ImageButtonOpenHour;
OpenHourInterval interval = new OpenHourInterval();
interval.Start = default(DateTime);
interval.End = default(DateTime);
var intervalCollection = Items.Where(p=>p.DayOfWeek == btn.Weekday).First();
intervalCollection.Add(interval);
ChildControlsCreated = false;
//Page.Response.Redirect(Page.Request.Url.AbsoluteUri);
//CreateGui();
// EnsureChildControls();
//Page.Response.Write("<body OnLoad='java script:__doPostBack('ForcePostBack','');'>");
//CreateControlHierarchy();
//CreateChildControls();
}
void InitItems()
{
List<OpenHourIntervalCollection> intervals = new List<OpenHourIntervalCollection>();
foreach (Weekday day in Enum.GetValues(typeof(Weekday)))
{
OpenHourIntervalCollection intervalCollection = new OpenHourIntervalCollection();
intervalCollection.DayOfWeek = day;
intervalCollection.Enabled = true;
OpenHourInterval interval = new OpenHourInterval();
interval.Start = default(DateTime);
interval.End = default(DateTime);
intervalCollection.Add(interval);
intervals.Add(intervalCollection);
}
Items = intervals;
}
public List<OpenHourIntervalCollection> Items
{
get
{
return ViewState["Items"] as List<OpenHourIntervalCollection>;
}
set
{
ViewState["Items"] = value;
}
}
}
}