我在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);
}
}
}
}
答案 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--;
}