簡體   English   中英

如何在C#.net中創建自定義日期時間選擇器

[英]How to make a custom datetimepicker in c#.net

我在c#.net中創建了一個名為MyDateTime的自定義控件作為datetimepicker。 它構建成功並且運行正常。但是當我單擊按鈕時它凍結了。我必須在下面顯示一個面板,但是沒有。我檢查代碼並確定。顯然有運行錯誤。請幫助我解決它

代碼:

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

您的程序卡在其中:

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

暫無
暫無

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

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