可自定义的 MonthCalendar 类型控件:第一部分






4.21/5 (17投票s)
2005年5月26日
4分钟阅读

186517

13846
一个真正可自定义的MonthCalendar类型控件。
引言
作为创建CRM软件包的团队成员,我负责项目的用户界面部分。所有CRM软件都需要约会日历。我最初选择使用MonthCalendar
控件来允许用户选择约会日期。创建约会后,我将新日期添加到MonthCalendar
控件的BoldedDates
数组中,以指示该日期有约会。我对MonthCalendar
控件在外观方面缺乏自定义选项感到沮丧。与市场部门(主要用户)的第一次会议中,他们要求将粗体日期更改为不同的颜色,并显示更完整的月份视图,其中显示每一天约会的缩写。月份视图还需要能够打印。
我决定创建自己的MonthCalendar
类型用户控件,该控件可用于选择日期并显示整个月份的较大尺寸以及约会缩写。这是我在.NET中创建的第一个Windows控件,我在VB5和VB6中有七年的Windows经验,但我主要是在过去两年中使用C#进行ASP.NET应用程序开发,使用GDI+创建在线图表。
我把开发分成了两部分。
第一部分。– 创建我自己的MonthCalendar
类型控件,其基本功能与.NET MonthCalendar
相同,并且能够自定义所有外观方面。
第二部分。– 实现完整的月份视图,包括约会缩写和打印功能。
本文仅涵盖第一部分。
背景
该控件包含两个Button
、一个Label
和一个PictureBox
。Button
用于移动到下一个或上一个月份。Label
显示月份和年份,而PictureBox
显示实际的日历。日历在PictureBox
的Paint
事件中绘制。该控件公开了一个额外的事件,SelectedDateChanged
。
可以更改以下属性
- 活动月份背景颜色。
- 非活动月份背景颜色。
- 标题背景颜色。
- 选中日期背景颜色。
- 选中日期字体颜色。
- 粗体日期字体颜色。
- 网格颜色。
- 控件背景颜色。
- 粗体日期使用的字体。
- 非粗体日期使用的字体。
可以启用或禁用以下属性
- 显示上一个和下一个按钮。
- 绘制网格。
- 在活动月份显示月份名称。
- 缩写标题中的星期几名称。
- 将周末日期显示为较深颜色。
测试应用程序演示了更改一些属性,并将SelectedDate
显示为窗体的标题。
使用代码
代码的整个结构基于一个7 x 6的网格,我用它来显示日历。一个7 x 6的整数数组保存关于网格中每个日期的数据,一个数组用于日期数字,一个数组用于月份数字。这些值决定了网格的每个单元格应该如何绘制。PictureBox
被分成一个矩形数组,这些矩形将在Paint
事件中使用。
该控件可以在任何使用标准MonthCalendar
控件的地方使用,它接受一个要加粗的日期数组。它可以调整大小以适应可用空间。
用适当的日期数据填充数组的函数是这一阶段最有趣的部分。请参见源代码中的FillDates()
。
关注点
该控件能够将周末日期显示为比本月其他日期略深的颜色。为此,我根据选择的颜色创建一个新颜色,并使用该颜色作为画笔。在这种情况下,每个RGB属性都是原始颜色的80%。
brushActive = new SolidBrush(p_ActiveMonthColor);
ActiveDarker = Color.FromArgb((int)(p_ActiveMonthColor.R*0.8),
(int)(p_ActiveMonthColor.G*0.8),
(int)(p_ActiveMonthColor.B*0.8));
brushActiveDarker = new SolidBrush(ActiveDarker);
该控件公开了一个额外的事件,SelectedDateChanged
。当选定日期更改时,将触发此事件。为此,我创建一个类来保存事件数据。此类必须派生自EventArgs
。
using System;
namespace MPK_Calendar
{
/// <summary>
/// Event argument class.
/// </summary>
public class SelectedDateChangedEventArgs:EventArgs
{
private DateTime pSelectedDate;
/// <summary>
/// Constructor
/// </summary>
/// <param name="dateSelected">Date </param>
public SelectedDateChangedEventArgs(DateTime dateSelected)
{
pSelectedDate = dateSelected;
}
/// <summary>
/// The selected date.
/// </summary>
public DateTime SelectedDate
{
get
{
return pSelectedDate;
}
}
}
}
声明事件的委托
public delegate void SelectedDateChangedEventHandler(object sender,
SelectedDateChangedEventArgs e);
提供一个public
事件成员
#region Custom events
/// <summary>
/// Event handler definition
/// </summary>
public event SelectedDateChangedEventHandler SelectedDateChanged;
创建一个protected
函数来引发事件
protected virtual void
OnSelectedDateChanged(SelectedDateChangedEventArgs eventArgs)
{
if(SelectedDateChanged!=null)
{
SelectedDateChanged(this,eventArgs);
}
}
#endregion Custom events
最后在演示应用程序的形式中使用该事件
private void mpK_Calendar1_SelectedDateChanged_1(object sender,
MPK_Calendar.SelectedDateChangedEventArgs e)
{
this.Text = e.SelectedDate.ToShortDateString();
}
众所周知,公共属性可以在属性编辑器中编辑。属性定义上方的两行代码允许我指定一个类别和一个说明,以便在属性编辑器中使用。
[Description("Grid color.")]
[Category("MPK_Calendar")]
public Color GridColor
{
get
{
return p_GridColor;
}
set
{
pGridColor=value;
this.picMPK_Cal.Invalidate();
}
}
历史
- 2005年11月8日 - 修复了更改月份时出现的错误。我还更改了日期信息的存储方式。