2017-06-18 55 views
0

我已經創建了一個名爲MyDateTime的自定義控件作爲c#.net中的datetimepicker。它建立成功,它運行ok.but當我點擊按鈕它凍結。我必須顯示在下面的面板,但它不。我檢查代碼,它是好的。顯然有一個runtim e錯誤。請幫助我解決這個問題如何在c#.net中製作自定義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); 
      } 
     } 
    } 
} 
+0

您是否嘗試過調試,所以你可以給我們一點程序凍結的更具體的細節?我認爲它卡在'SetDayBoxSize'方法中。 – Deadzone

+0

我沒有遇到任何錯誤,只是它凍結了 – Shayan

+0

我沒有說過你有錯誤,但是當你的程序凍結時它最有可能意味着它被卡住了,因爲操作繁重,或者在這裏看起來更像是一個無限循環。 – Deadzone

回答

0

您的程序裏面卡住:

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返回值。這意味着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--; 
} 
+0

你是如何發現卡住 – Shayan

+0

@Shayan正如我在我的評論中解釋你的問題,你的程序將凍結,因爲它目前很忙。你看到你的程序在按下按鈕時會凍結,你應該看看你處理點擊事件的地方。之後,開始尋找任何沉重的操作,如果沒有,比這意味着它很可能會陷入一個無休止的循環,這是由於思考不周而造成的,在你的情況下是while循環。 – Deadzone

+0

@Shayan如果我的答案解決了您的問題,請考慮通過在向下投票圖標下按圓圈複選標記來接受。 – Deadzone