Я пытаюсь создать собственный календарь, в который я помещаю события.
Я создал основной пользовательский элемент управления, который просто перечисляет события:
namespace MyControls
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
public class Calendar : CompositeDataBoundControl
{
protected override Int32 CreateChildControls(IEnumerable dataSource, Boolean dataBinding)
{
Int32 itemCounter = 0;
if (dataSource != null)
{
IEnumerator dataSourceEnumerator = dataSource.GetEnumerator();
while (dataSourceEnumerator.MoveNext())
{
LinkButton eventLink = new LinkButton();
eventLink.Click += new EventHandler(EventLinkClick);
HtmlGenericControl eventContainer = new HtmlGenericControl();
eventContainer.Controls.Add(eventLink);
eventContainer.TagName = "p";
this.Controls.Add(eventContainer);
if (dataBinding)
{
CalendarEvent currentEvent = (CalendarEvent) dataSourceEnumerator.Current;
eventLink.CommandArgument = String.Concat(currentEvent.Name, "§", currentEvent.Day.ToBinary());
eventLink.Text = currentEvent.Name;
eventLink.ToolTip = currentEvent.Description;
}
itemCounter++;
}
}
return itemCounter;
}
protected void EventLinkClick(Object sender, EventArgs e)
{
}
}
}
Элемент управленияработает, когда я передаю ему List<CalendarEvent>
, он отображает каждое событие LinkButton
внутри его собственного <p />
, когда я нажимаю LinkButton
, вызывается EventLinkClick
метод, и после обратной передачи LinkButton
s все ещетам с их значениями.
Однако мне не нужен простой список событий, мне нужно поместить свои события в календарь, в правильный день.
Я создаю свой календарькак это:
Int32 year = 2011;
Table monthTable = null;
TableRow weekRow = null;
for (DateTime day = new DateTime(year, 1, 1); day.Year == year; day = day.AddDays(1))
{
if (day.Day == 1)
{
HtmlGenericControl monthName = new HtmlGenericControl();
monthName.InnerText = CultureInfo.CurrentUICulture.DateTimeFormat.GetMonthName(day.Month);
monthName.TagName = "h2";
this.Controls.Add(monthName);
monthTable = new Table();
TableHeaderRow headerRow = new TableHeaderRow();
headerRow.TableSection = TableRowSection.TableHeader;
monthTable.Rows.Add(headerRow);
for (Int32 i = 0; i < 7; i++)
{
TableHeaderCell dayOfWeekCell = new TableHeaderCell();
dayOfWeekCell.Text = CultureInfo.CurrentUICulture.DateTimeFormat.GetShortestDayName((DayOfWeek) i);
headerRow.Cells.Add(dayOfWeekCell);
}
weekRow = new TableRow();
weekRow.TableSection = TableRowSection.TableBody;
for (Int32 i = 0; i < (Int32) day.DayOfWeek; i++)
{
weekRow.Cells.Add(new TableCell());
}
}
if (day.DayOfWeek == DayOfWeek.Sunday && day.Day != 1)
{
monthTable.Rows.Add(weekRow);
weekRow = new TableRow();
weekRow.TableSection = TableRowSection.TableBody;
}
TableCell dayCell = new TableCell();
dayCell.Text = Convert.ToString(day.Day);
weekRow.Cells.Add(dayCell);
if (day.Day == DateTime.DaysInMonth(day.Year, day.Month))
{
for (Int32 i = (Int32) day.DayOfWeek; i < 6; i++)
{
weekRow.Cells.Add(new TableCell());
}
monthTable.Rows.Add(weekRow);
this.Controls.Add(monthTable);
}
}
, что приводит к чему-то вроде этого:
.
Теперь, как я могу объединить две вещи?
Я придумал приведение параметра dataSource
к IEnumerable<CalendarEvents>
, и после строки dayCell.Text = Convert.ToString(day.Day);
я получаю события дня от IEnumerable<CalendarEvents>
через LINQ.
Однако это прерывается наpostback, потому что когда элемент управления воссоздает себя после обратной передачи, параметр dataSource
полон nulПоэтому я не могу получить события дня, поэтому не могу воссоздать элементы управления.
Я не смог ничего найти в сети по этому поводу, и я полностью застрял.
Я что-то упускаю (или играю)?Что мне нужно сделать, чтобы добиться того, что я ищу?
Обновление # 1
Как предложил StriplingWarrior Я попытался сохранить dataSource
во ViewState, однакоЯ резко потерпел неудачу.
Я попробовал вот что: в начале CreateChildControls
метода я поместил
if (dataBinding)
{
this.ViewState.Add("myDataSource", dataSource);
}
IEnumerable myDataSource = (IEnumerable) this.ViewState["myDataSource"];
и заменил каждый вызов на dataSource
на myDataSource
.
Тем не менее, когда на странице появляется сообщение this.ViewState["myDataSource"]
, равное null
, и я возвращаюсь к исходной точке.
Я начинаю сожалеть, когда решил перейти с CompositeDataBoundControl
...: \
Обновление # 2
Я попытался создать новый проект, содержащий только пользовательский элемент управления, и переписал его с нуля, и Предложение StriplingWarrior сработало:
if (dataBinding)
{
this.ViewState.Add("DataSource", dataSource);
}
else
{
dataSource = (IEnumerable) this.ViewState["DataSource"];
}
Однако я не смог точно определить, что было причиной this.ViewState["DataSource"]
в исходном решении.