如何在c#.net中创建自定义datetimepicker

时间:2017-06-18 14:14:58

标签: c# custom-controls datetimepicker

我在c#.net中创建了一个名为MyDateTime的自定义控件作为datetimepicker。它构建成功并且运行正常。但是当我点击按钮时它会冻结。我必须在下面显示一个面板但它没有。我检查代码并且没关系。显然有一个runtim e错误。请帮助我解决它

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Globalization;

namespace WindowsFormsApplication5
{
    public partial class MyDateTime : UserControl
    {
        private Button DropButton;
        private MaskedTextBox maskedTextBox1;
        private MonCal monCal = null;
        public class MonCalEventArgs : EventArgs
        {
            private DateTime selectedDate;

            public MonCalEventArgs(DateTime sentSelectedDate)
            {
                selectedDate = sentSelectedDate;
            }

            public string SelectedDate { get { return selectedDate.ToString("MM/dd/yyyy"); } }
        }

        public class HighlightedDates
        {
            public DateTime Date;
            public Point Position = new Point(0, 0);
            public Color DateColor;
            public Color BoxColor;
            public Color BackgroundColor;
            public Boolean Bold;

            public HighlightedDates(DateTime date)
            {
                this.Date = date;
                this.DateColor = this.BoxColor = this.BackgroundColor = Color.Empty;
                this.Bold = true;
            }

            public HighlightedDates(DateTime date, Color dateColor, Boolean bold)
            {
                this.Date = date;
                this.BackgroundColor = this.BoxColor = Color.Empty;
                this.DateColor = dateColor;
                this.Bold = bold;
            }

            public HighlightedDates(DateTime date, Color dateColor, Color boxColor,
                Color backgroundColor, Boolean bold)
            {
                this.Date = date;
                this.DateColor = dateColor;
                this.BoxColor = boxColor;
                this.BackgroundColor = backgroundColor;
                this.Bold = bold;
            }
        }


        public MyDateTime()
        {
            InitializeComponent();
            this.SuspendLayout();

            maskedTextBox1 = new MaskedTextBox();
            maskedTextBox1.Location = new Point(0, 0);
            maskedTextBox1.Mask = "00/00/0000";
            maskedTextBox1.Name = "maskedTextBox1";
            maskedTextBox1.Size = new Size(139, 20);
            maskedTextBox1.TabIndex = 0;
            maskedTextBox1.ValidatingType = typeof(DateTime);

            DropButton = new Button();
            DropButton.Size = new Size(16, 16);
            DropButton.FlatStyle = FlatStyle.Standard;
            DropButton.BackColor = Color.White;
            DropButton.BackgroundImage = Image.FromFile(@"C:\Users\JAVAD\documents\visual studio 2015\Projects\WindowsFormsApplication5\WindowsFormsApplication5\CalendarIcon.ico");
            DropButton.BackgroundImageLayout = ImageLayout.Tile;
            DropButton.Location = new Point(maskedTextBox1.Width - 20, 0);
            DropButton.Click += new EventHandler(DropButton_Click);
            DropButton.Cursor = Cursors.Arrow;
            maskedTextBox1.Controls.Add(DropButton);
            maskedTextBox1.Text = DateTime.Now.ToString("MM/dd/yyy");

            this.Controls.Add(maskedTextBox1);

            this.ResumeLayout();
            // InitializeComponent();
        }
        void DropButton_Click(object sender, EventArgs e)
        {
            string a= maskedTextBox1.Text;
            string []aa= a.Split('/');
            List<HighlightedDates> hlDates = new List<HighlightedDates>();
            hlDates.Add(new HighlightedDates(new DateTime(int.Parse(aa[2]), int.Parse(aa[0]), int.Parse(aa[1])),
                Color.Red, Color.Blue, Color.Pink, true));

            monCal = new MonCal(hlDates);
            monCal.monCalControlHandler +=
                new MonCal.MonCalControlHandler(monCal_monCalControlHandler);
            monCal.Location = new Point(20, 20);
            this.Controls.Add(monCal);
        }

        void monCal_monCalControlHandler(object sender, MonCalEventArgs e)
        {
            maskedTextBox1.Text = e.SelectedDate;
            this.Controls.Remove(monCal);
            monCal = null;
        }

        internal class MonCal : MonthCalendar
        {
            protected static int WM_PAINT = 0x000F;
            private Rectangle dayBox;
            private int dayTop = 0;
            private SelectionRange range;

            private List<HighlightedDates> highlightedDates;

            public delegate void MonCalControlHandler(object sender, MonCalEventArgs e);
            public event MonCalControlHandler monCalControlHandler;

            public MonCal(List<HighlightedDates> HighlightedDates)
            {
                this.ShowTodayCircle = false;
                this.highlightedDates = HighlightedDates;
                range = GetDisplayRange(false);
                SetDayBoxSize();
                SetPosition(this.highlightedDates);

            }

            private void SetDayBoxSize()
            {
                int bottom = this.Height;

                while (HitTest(1, dayTop).HitArea != HitArea.Date &&
                    HitTest(1, dayTop).HitArea != HitArea.PrevMonthDate) dayTop++;

                while (HitTest(1, bottom).HitArea != HitArea.Date &&
                    HitTest(1, bottom).HitArea != HitArea.NextMonthDate) bottom--;

                dayBox = new Rectangle();
                dayBox.Size = new Size(this.Width / 7, (bottom - dayTop) / 6);
            }

            private void SetPosition(List<HighlightedDates> hlDates)
            {
                int row = 0, col = 0;

                hlDates.ForEach(delegate (HighlightedDates date)
                {
                    if (date.Date >= range.Start && date.Date <= range.End)
                    {
                        TimeSpan span = date.Date.Subtract(range.Start);
                        row = span.Days / 7;
                        col = span.Days % 7;
                        date.Position = new Point(row, col);
                    }
                });
            }

            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                if (m.Msg == WM_PAINT)
                {
                    Graphics g = Graphics.FromHwnd(this.Handle);
                    PaintEventArgs pea =
                        new PaintEventArgs(g, new Rectangle(0, 0, this.Width, this.Height));
                    OnPaint(pea);
                }
            }

            protected override void OnPaint(PaintEventArgs pe)
            {
                base.OnPaint(pe);

                Graphics g = pe.Graphics;
                Rectangle backgroundRect;

                highlightedDates.ForEach(delegate (HighlightedDates date)
                {
                    backgroundRect = new Rectangle(
                                date.Position.Y * dayBox.Width + 1,
                                date.Position.X * dayBox.Height + dayTop,
                                dayBox.Width, dayBox.Height);

                    if (date.BackgroundColor != Color.Empty)
                    {
                        using (Brush brush = new SolidBrush(date.BackgroundColor))
                        {
                            g.FillRectangle(brush, backgroundRect);
                        }
                    }

                    if (date.Bold || date.DateColor != Color.Empty)
                    {
                        using (Font textFont =
                            new Font(Font, (date.Bold ? FontStyle.Bold : FontStyle.Regular)))
                        {
                            TextRenderer.DrawText(g, date.Date.Day.ToString(), textFont,
                                backgroundRect, date.DateColor,
                                TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
                        }
                    }

                    if (date.BoxColor != Color.Empty)
                    {
                        using (Pen pen = new Pen(date.BoxColor))
                        {
                            Rectangle boxRect = new Rectangle(
                             date.Position.Y * dayBox.Width + 1,
                                date.Position.X * dayBox.Height + dayTop,
                                dayBox.Width, dayBox.Height);
                            g.DrawRectangle(pen, boxRect);
                        }
                    }
                });

            }
            protected override void OnDateSelected(DateRangeEventArgs drevent)
            {
                base.OnDateSelected(drevent);
                MonCalEventArgs args = new MonCalEventArgs(drevent.Start);
                monCalControlHandler(this, args);
                this.Dispose();
            }
            protected override void OnPaintBackground(PaintEventArgs pevent)
            {
                base.OnPaintBackground(pevent);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

你的程序卡在里面:

while (HitTest(1, dayTop).HitArea != HitArea.Date &&
        HitTest(1, dayTop).HitArea != HitArea.PrevMonthDate) dayTop++;

while (HitTest(1, bottom).HitArea != HitArea.Date &&
        HitTest(1, bottom).HitArea != HitArea.NextMonthDate) bottom--;

这是因为HitTest(1, dayTop).HitArea返回HitArea.Nowhere的值。这意味着while循环中的所有条件都将始终正确,从而导致程序冻结,因为它会无意识地永久地停留在那里。

我不确定您要尝试实现的目标,但一个简单的解决方法是将以下行添加到您的while循环中:

while (HitTest(1, dayTop).HitArea != HitArea.Nowhere &&
       HitTest(1, dayTop).HitArea != HitArea.Date &&
       HitTest(1, dayTop).HitArea != HitArea.PrevMonthDate)
{
    dayTop++;
}

while (HitTest(1, dayTop).HitArea != HitArea.Nowhere &&
       HitTest(1, bottom).HitArea != HitArea.Date &&
       HitTest(1, bottom).HitArea != HitArea.NextMonthDate)
{
    bottom--;
}