ASP.NET:按钮的OnClick事件和未触发的匿名事件

时间:2009-09-11 05:24:28

标签: asp.net

我正在创建一个时间选择器用户控件,它首先显示当天的按钮,然后是接下来的几天:

|今天| |星期一| |星期二| |星期三|

当用户点击其中一个按钮时,控件将在日期按钮下方显示一组小时按钮:

|今天| |星期一| |星期二| |星期三|

| 7:00 | | 8:00 | | 9:00 | | 10:00 | | 11:00 | |中午| | 1:00 | | 2:00 |

到目前为止,我的控制工作正常。然后,当用户点击一个小时按钮时应该发生的是一小时分钟按钮(相隔5分钟)将显示该小时:

|今天| |星期一| |星期二| |星期三|

| 7:00 | | 8:00 | | 9:00 | | 10:00 | | 11:00 | |中午| | 1:00 | | 2:00 |

| 9:00 | | 9:05 | | 9:10 | | 9:15 | | 9:20 | | 9:25 | | 9:30 | | 9:35 |

而不是发生这种情况,控件似乎重置了自己并返回到只显示日期按钮的部分。小时按钮的OnClick事件甚至没有触发(我通过重载OnClick方法并将Page.Response.Write(“它的触发”)放入其中来测试它 - 当我将它放在重载的OnClick方法中时,这确实有效白天按钮)。

这是我的代码(所有内容都放在带有代码的用户控件上 - .ascx标记页面只包含< @%Control%>标记):

public partial class TimePicker : System.Web.UI.UserControl
{
    public TimePicker()
    {
        this.Controls.Add(new TeeTimePanel());
    }

    private class TimePanel : Panel
    {
        public TimePanel()
        {
            Days = new Panel();
            this.Controls.Add(Days);

            Hours = new Panel();
            this.Controls.Add(Hours);

            Minutes = new Panel();
            this.Controls.Add(Minutes);

            DayButton.CreateDayButtons(this);
        }

        public void CreateHourButtons(DateTime day)
        {
            HourButton.CreateHourButtons(day, this);
        }

        public void CreateMinuteButtons(DateTime time) 
        {
            MinuteButton.CreateMinuteButtons(time.Date, time.Hour, this);
        }

        public Panel Days, Hours, Minutes;
    }

    private class DayButton : Button
    {
        private DayButton(DateTime day, TimePanel parent)
        {
            this.date = day;

            if (day.Date == DateTime.Today)
            {
                this.Text = "Today";
            }
            else
            {
                this.Text = day.ToString("dddd");
            }

            this.Click += delegate
            {
                parent.CreateHourButtons(day);
            };
        }

        private DateTime date;

        public static void CreateDayButtons(TimePanel parent)
        {
            for (int i = 0; i < 5; i++)
            {
                DayButton b = new DayButton(DateTime.Today.AddDays(i), parent);
                parent.Days.Controls.Add(b);
            }
        }
    }

    private class HourButton : Button
    {
        private HourButton(DateTime day, int hour, bool enabled, TimePanel parent)
        {
            this.Enabled = enabled;
            this.time = day.Date.AddHours(hour);

            if (hour < 12)
            {
                this.Text = hour.ToString() + ":00";
            }
            else if (hour == 12)
            {
                this.Text = "Noon";
            }
            else
            {
                this.Text = (hour - 12).ToString() + ":00";
            }

            this.Click += delegate
            {
                parent.CreateMinuteButtons(day.AddHours(hour));
            };
        }

        public static void CreateHourButtons(DateTime day, TimePanel parent) 
        {
            Dictionary<int, bool> availableHours = new Dictionary<int, bool>();

            //This randomly generates available hours and will eventually
            //be replaced with code that accesses a database
            Random r = new Random();
            for (int i = 7; i <= 19; i++)
            {
                availableHours.Add(i, r.Next(5) != 0);
            }

            foreach (KeyValuePair<int, bool> kvp in availableHours)
            {
                HourButton b = new HourButton(day.Date, kvp.Key, kvp.Value, parent);
                parent.Hours.Controls.Add(b);
            }
        }

        private DateTime time;
    }

    private class MinuteButton : Button
    {
        private MinuteButton(DateTime day, int hour, int minute)
        {
            this.time = day.Date.AddHours(hour).AddMinutes(minute);

            if (hour <= 12)
            {
                this.Text = hour.ToString() + ":";
            }
            else
            {
                this.Text = (hour - 12).ToString() + ":";
            }

            this.Text += minute.ToString("d2");
        }

        public static void CreateMinuteButtons(DateTime day, int hour, Panel target)
        {
            List<int> availableTimes = new List<int>();

            //This randomly generates available times
            Random r = new Random();
            for (int i = 0; i < 60; i += 5)
            {
                if (r.Next(2) != 0)
                {
                    availableTimes.Add(i);
                }
            }

            foreach (int i in availableTimes)
            {
                MinuteButton b = new MinuteButton(day, hour, i);
                target.Controls.Add(b);
            }
        }

        private DateTime time;
    }
}

任何人都可以解释为什么匿名方法适用于DayButton,但是当我为HourButton使用几乎相同的代码时,它不是吗?我确信它与ASP.NET的工作方式有关,而不是C#。

2 个答案:

答案 0 :(得分:1)

确保在回发后重建控件或不会触发事件。

答案 1 :(得分:0)

你说这更像是一个asp.net问题,而不是c#。您需要了解页面的生命周期。当我第一次开始做网络表格时,这就让我感到高兴,而且它吸引了很多新人。

初始化TimePicker控件时,构造函数会运行并调用此方法:DayButton.CreateDayButtons(this);这将创建你的DayButtons。

this.Click += delegate
{
     parent.CreateHourButtons(day);
};

使用此代码,您可以尝试在ASP.NET上不知道的按钮上触发事件,因为它已动态添加到页面中。因此,正如ChaosPandion所述,控件不会存在于页面上,直到您再次添加它们为止,因此您的事件将如何被触发?!

为我动态添加控件一直是关于回发和获取值等的头疼问题。我个人会看看做这样的客户端。