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






4.43/5 (7投票s)
2005年11月16日
2分钟阅读

81360

3312
一款真正可定制的 MonthCalendar 类型控件。
显示预约详情的截图。
打印预览窗口的一部分。
引言
这是我文章的第二部分:可定制的 MonthCalendar 类型控件。为 MonthCalendar
控件添加的新功能包括:
- 添加预约到控件中。这将取代
BoldedDates
数组。每个预约将包含日期、开始和结束时间以及描述。日期将在日历中以粗体显示;要查看预约信息,请右键单击该日期。 - 月历的打印功能。将打印月历网格和每天最多四个预约。
- 已向日历控件添加了两个新类,一个预约类和一个预约集合类。在绘制日历时,我会检查是否有任何预约与正在绘制的日期匹配。如果有,该日期将以粗体显示。我希望在不向日历添加任何其他组件的情况下显示预约数据。为了实现这一点,我会在按下鼠标右键时在上下文菜单中显示预约数据。
- 打印日历的过程与
Paint
例程非常相似,只是添加了四个用于绘制预约信息的矩形。
背景
请参阅本文的第一部分:可定制的 MonthCalendar 类型控件。
使用代码
该控件可以在任何可以使用标准 MonthCalendar
控件的地方使用,并且它接受要加粗的日期数组。可以调整其大小以适应可用空间。
创建预约
private void Form1_Load(object sender, System.EventArgs e)
{
mpK_Calendar1.SelectedDateChanged+= new
SelectedDateChangedEventHandler(mpK_Calendar1_SelectedDateChanged);
mpK_Calendar1.SelectedDate=DateTime.Now;
//part 2
//At this point, the assumption is that
//appointments are added in chronological order
mpK_Calendar1.Appointments.Add(new DateTime(2005,11,1,6,0,0),
new DateTime(2005,11,1,7,0,0),"TEST DESCRIPTION");
mpK_Calendar1.Appointments.Add(new DateTime(2005,11,1,8,0,0),
new DateTime(2005,11,1,9,0,0),"TEST DESCRIPTION");
mpK_Calendar1.Appointments.Add(new DateTime(2005,11,1,10,0,0),
new DateTime(2005,11,1,11,0,0),"TEST DESCRIPTION");
}
新的预约和预约集合类
public class clsAppt
{
public DateTime ApptStart;
public DateTime ApptEnd;
public string strDesc;
public clsAppt(DateTime ApptStartIn,
DateTime ApptEndIn,string strDescIn)
{
ApptStart = ApptStartIn;
ApptEnd = ApptEndIn;
strDesc = strDescIn;
}
}
public class clsApptColl:System.Collections.CollectionBase
{
public clsApptColl()
{
}
public void Add(clsAppt Appt)
{
List.Add(Appt);
}
public void Add(DateTime ApptStartIn,
DateTime ApptEndIn,string strDescIn)
{
List.Add(new clsAppt(ApptStartIn,ApptEndIn,strDescIn));
}
public void Remove(int intIndex)
{
if(intIndex>-1 && intIndex<List.Count)
{
List.RemoveAt(intIndex);
}
}
public clsAppt Item(int intIndex)
{
return (clsAppt) List[intIndex];
}
public int ListCount()
{
return List.Count;
}
}
关注点
这是动态创建右键单击上下文菜单的代码
//part 2
//A context menu is used to display the full details of each appointment.
//Based on the X,Y coordinates of the mouse,
//check to see if there are any appointments to display.
//dynamically create context menu
ContextMenu contextMenu1 = new ContextMenu();
//counter
int intApptCtr=0;
contextMenu1.MenuItems.Clear();
if(e.Button==MouseButtons.Right)//right mouse
{
for(int k=0;k<Appointments.ListCount();k++)
{
if(Appointments.Item(k).ApptStart.Date==this.SelectedDate)
{
if(intApptCtr>0)
{
contextMenu1.MenuItems.Add(contextMenu1.MenuItems.Count,
new MenuItem("-"));
}
contextMenu1.MenuItems.Add(contextMenu1.MenuItems.Count,
new MenuItem("Date: " +
Appointments.Item(k).ApptStart.Date.ToLongDateString()));
contextMenu1.MenuItems.Add(contextMenu1.MenuItems.Count,
new MenuItem("Time: " +
Appointments.Item(k).ApptStart.TimeOfDay +
" - " + Appointments.Item(k).ApptEnd.TimeOfDay));
contextMenu1.MenuItems.Add(contextMenu1.MenuItems.Count,
new MenuItem("Subject: " +
Appointments.Item(k).strDesc));
intApptCtr++;
}
}
if(intApptCtr>0)
{
//show context menu
contextMenu1.Show(this,new Point(e.X,e.Y));
}
}
else//left mouse
{
}
//part 2
在使用 GDI+ 绘制窗体或进行打印时,这里有一些我发现有用的事项。
在绘制文本时,我更喜欢将文本绘制到矩形中,并使用 StringFormat
对象来正确布局文本。
//string format for calendar body
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
sf.Trimming = StringTrimming.EllipsisCharacter;
Alignment
属性确定文本在矩形内的左右放置。LineAlignment
属性确定文本在矩形内的上下放置。Trimming
属性确定如果文本过长超出矩形会发生什么情况。
如果您需要标准的颜色画笔,可以创建一个
new SolidBrush(Color.Black);
或者使用 Brushes
类中的一个
Brushes.Black