Как разместить дочерние элементы управления в определенном порядке при привязке пользовательского элемента управления? - PullRequest
1 голос
/ 20 мая 2011

Я пытаюсь создать собственный календарь, в который я помещаю события.

Я создал основной пользовательский элемент управления, который просто перечисляет события:

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);
    }
}

, что приводит к чему-то вроде этого:

An example of my calendar.

Теперь, как я могу объединить две вещи?

Я придумал приведение параметра 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"] в исходном решении.

1 Ответ

1 голос
/ 20 мая 2011

У вас проблемы с ViewState.Вы можете либо отключить viewstate на вашем элементе управления, либо записать этот элемент управления таким образом, чтобы он сохранял информацию, которая ему необходима, во ViewState, чтобы при последующих постбэках ему не нужно было выполнять повторную привязку к источнику данных.

...