65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (7投票s)

2005年11月16日

2分钟阅读

viewsIcon

81360

downloadIcon

3312

一款真正可定制的 MonthCalendar 类型控件。

Sample Image

显示预约详情的截图。

Sample Image

打印预览窗口的一部分。

引言

这是我文章的第二部分:可定制的 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
© . All rights reserved.