簡體   English   中英

綁定自定義控件時如何按一定順序放置子控件?

[英]How to place child controls in a certain order when binding a custom control?

我想要實現的是一個自定義日歷,用於放置事件。

我創建了一個基本的自定義控件,該控件僅列出事件:

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>它將在其自己的<p />顯示每個事件的LinkButton ,當我單擊LinkButton ,將調用EventLinkClick方法,並且在回發之后, LinkButton仍帶有它們的值。

但是,我不需要事件的明細清單,我需要將事件放在正確日期的日歷中。

我這樣創建日歷:

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

產生這樣的東西:

我的日歷示例

現在,我該如何整合這兩件事?

dayCell.Text = Convert.ToString(day.Day);是將dataSource參數轉換為IEnumerable<CalendarEvents>並在dayCell.Text = Convert.ToString(day.Day); 我通過LINQ從IEnumerable<CalendarEvents>獲取當天的事件。

但是,這在回發時會中斷,因為在回發后控件重新創建自身時, dataSource參數充滿了null,因此我無法獲取當天的事件,因此無法重新創建控件。

我在網上找不到任何關於此的信息,而且我完全陷入了困境。

我是否想念(或弄亂)某些東西? 我應該怎么做才能達到我想要的?

更新#1

正如StriplingWarrior所建議的那樣,我試圖將dataSource保存在ViewState中,但是我失敗了。

我嘗試的是:在放置的CreateChildControls方法的開頭

if (dataBinding)
{
    this.ViewState.Add("myDataSource", dataSource);
}

IEnumerable myDataSource = (IEnumerable) this.ViewState["myDataSource"];

並用myDataSource替換對dataSource每次調用。

但是,當頁面帖子支持this.ViewState["myDataSource"]null ,我回到第一位。

當我決定使用CompositeDataBoundControl ...時,我開始感到后悔。

更新#2

我試圖創建一個僅包含自定義控件的新項目,並從頭開始重寫了它, StriplingWarrior的建議起作用了:

if (dataBinding)
{
    this.ViewState.Add("DataSource", dataSource);
}
else
{
    dataSource = (IEnumerable) this.ViewState["DataSource"];
}

但是,我無法確定導致原始解決方案中this.ViewState["DataSource"]的原因。

您遇到了ViewState問題。 您可以在控件上禁用viewstate,或以將控件所需的信息保存在ViewState中的方式編寫控件,因此在以后的回發中不需要將其重新綁定到數據源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM