📄 mycalendar.cs
字号:
using System;
using System.Collections;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Opportune.CalEx
{
class MyCalendar
{
/// <summary>
/// 以下几个成员变量分别是:
/// 1,本类生成时传递进来的"当前时间"
/// 2,我的月(42天)的对象
/// 3,当前选中的日期在我的月的对象中的序号(0-41)
/// 4,本类所对应的控件,应该是一个 Panel ,即 panel3
/// 5,保存日期和图片的 hash 表
/// </summary>
private DateTime _now;
private MonthEx _mymonth;
private int _selected;
private Control _control;
private Hashtable _hash;
public MyCalendar(Control owner, DateTime now)
{
_control = owner;
_now = now;
_mymonth = new MonthEx(now.Year, now.Month);
_hash = new Hashtable(100, 0.2f);
for (int i = 0; i < MonthEx.DATECOUNT; i++)
{
if (_mymonth.Dates[i].date == _now.Date)
{
_selected = i;
break;
}
}
}
public int Year
{
get
{
return _mymonth.Year;
}
set
{
if (_mymonth.Year == value)
return;
MonthEx m = new MonthEx(value, _mymonth.Month);
_mymonth = null;
_mymonth = m;
((IMyCalChanged)(_control.Parent)).DoCalChanged(_mymonth.Year, _mymonth.Month);
}
}
public int Month
{
get
{
return _mymonth.Month;
}
set
{
if (_mymonth.Month == value)
return;
MonthEx m = new MonthEx(_mymonth.Year, Month);
if (_selected >= 0)
{
for (int i = 0; i < MonthEx.DATECOUNT; i++)
{
if (_mymonth.Dates[_selected].date == m.Dates[i].date)
{
_selected = i;
break;
}
}
}
_mymonth = null;
_mymonth = m;
((IMyCalChanged)(_control.Parent)).DoCalChanged(_mymonth.Year, _mymonth.Month);
}
}
public void AdvanceMonth(bool bNextMonth)
{
DateTime dtSelected = DateTime.Now;
if (_selected >= 0)
dtSelected = _mymonth.Dates[_selected].date;
MonthEx m;
if (bNextMonth)
m = _mymonth.NextMonth;
else
m = _mymonth.PrevMonth;
_mymonth = null;
_mymonth = m;
if (_selected >= 0)
{
for (int i = 0; i < MonthEx.DATECOUNT; i++)
{
if (_mymonth.Dates[i].date == dtSelected)
{
_selected = i;
break;
}
}
}
((IMyCalChanged)(_control.Parent)).DoCalChanged(_mymonth.Year, _mymonth.Month);
}
public void Paint(Graphics g)
{
int width = _control.Width / 7;
int height = _control.Height / 6;
Pen pen = new Pen(Color.Gray, 1);
int i, j, x, y;
x = 0;
y = height * 6;
for (i = 0; i < 8; i++)
{
if (i == 0)
x = 0;
else
x += width;
g.DrawLine(pen, x, 0, x, y);
}
x = width * 7;
y = 0;
for (i = 0; i < 7; i++)
{
if (i == 0)
y = 0;
else if(i == 6)
y += height - 1;
else
y += height;
g.DrawLine(pen, 0, y, x, y);
}
Font f = new Font("Arial", 12, FontStyle.Regular);
SolidBrush brToday = new SolidBrush(Color.Red);
SolidBrush brCurr = new SolidBrush(Color.Black);
SolidBrush brOther = new SolidBrush(Color.LightGray);
Image img;
for (i = 0; i < 7; i++)
{
for (j = 0; j < 6; j++)
{
RectangleF rect = new RectangleF(i * width, j * height,
(i + 1) * width, (j + 1) * height);
x = j * 7 + i;
y = _mymonth.Dates[x].date.Day;
if (_mymonth.Dates[x].date == _now.Date)
g.DrawString(y.ToString(), f, brToday, rect);
else if (_mymonth.Dates[x].month == MonthEx.IN_WHICH_MONTH.IN_CURRENT_MONTH)
g.DrawString(y.ToString(), f, brCurr, rect);
else
g.DrawString(y.ToString(), f, brOther, rect);
img = GetImage(_mymonth.Dates[x].date);
if (img != null)
g.DrawImage(img, (int)(rect.Left + width / 2), (int)(rect.Top + height / 2));
}
}
RedrawOneCell(g, _selected);
}
public void OnClick(int x, int y)
{
int width = _control.Width / 7;
int height = _control.Height / 6;
int sel = (y / height) * 7 + x / width;
if (sel < 0 || sel >= MonthEx.DATECOUNT)
return;
DateTime clickedDateTime = _mymonth.Dates[sel].date;
bool bClickedImage = false;
if ((x % width) > width / 2 && (y % height) > height / 2)
bClickedImage = true;
if (_selected != sel)
{
int old = _selected;
_selected = sel;
if (old >= 0)
{
_control.Invalidate(GetRectByIndex(old));
_control.Update();
}
_control.Invalidate(GetRectByIndex(_selected));
_control.Update();
if (_mymonth.Dates[sel].month == MonthEx.IN_WHICH_MONTH.IN_PREV_MONTH)
AdvanceMonth(false);
else if (_mymonth.Dates[sel].month == MonthEx.IN_WHICH_MONTH.IN_NEXT_MONTH)
AdvanceMonth(true);
else
((IMyCalChanged)(_control.Parent)).DoSelChanged(clickedDateTime, _selected);
}
if (bClickedImage)
{
((IMyCalChanged)(_control.Parent)).DoImageClicked(clickedDateTime, GetImage(clickedDateTime));
return;
}
}
public void MakeTodayVisible()
{
if (_mymonth.Year == _now.Year && _mymonth.Month == _now.Month)
{
int index = this.GetIndexByDate(_now.Date);
if(index == _selected)
return;
Rectangle rect = this.GetRectByIndex(index);
this.OnClick(rect.Left + 2, rect.Top + 2);
return;
}
MonthEx m = new MonthEx(_now.Year, _now.Month);
_mymonth = null;
_mymonth = m;
for (int i = 0; i < MonthEx.DATECOUNT; i++)
{
if (_mymonth.Dates[i].date == _now.Date)
{
_selected = i;
break;
}
}
((IMyCalChanged)(_control.Parent)).DoCalChanged(_mymonth.Year, _mymonth.Month);
}
public void RedrawOneCell(Graphics g, int index)
{
if (index < 0 || index >= MonthEx.DATECOUNT)
return;
Rectangle rect = GetRectByIndex(index);
bool selected;
if (index == _selected)
selected = true;
else
selected = false;
SolidBrush back_brush;
if (selected)
back_brush = new SolidBrush(Color.Cyan);
else
back_brush = new SolidBrush(Color.Transparent);
Rectangle back_rect = new Rectangle(rect.Left, rect.Top,
rect.Width, rect.Height);
g.FillRectangle(back_brush, back_rect);
Font f = new Font("Arial", 12, FontStyle.Regular);
SolidBrush br;
if (_mymonth.Dates[index].date == _now.Date )
br = new SolidBrush(Color.Red);
else if (_mymonth.Dates[index].month == MonthEx.IN_WHICH_MONTH.IN_CURRENT_MONTH)
br = new SolidBrush(Color.Black);
else
br = new SolidBrush(Color.LightGray);
g.DrawString(_mymonth.Dates[index].date.Day.ToString(), f, br, back_rect);
Image img = GetImage(_mymonth.Dates[index].date);
if (img != null)
g.DrawImage(img, (int)(rect.Left + rect.Width / 2), (int)(rect.Top + rect.Height / 2));
}
public int GetIndexByRect(Rectangle rect)
{
if (rect.Width == 0 || rect.Height == 0)
return -1;
if (rect.Width >= _control.Width || rect.Height >= _control.Height)
return -2;
if(rect.Width % _control.Width != 0)
return -3;
if (rect.Height % _control.Height != 0)
return -4;
int width = _control.Width / 7;
int height = _control.Height / 6;
int index = (rect.Top / height) * 7 + (rect.Left / width);
if (index < 0 || index >= MonthEx.DATECOUNT)
return -5;
return index;
}
public Rectangle GetRectByIndex(int index)
{
if (index < 0 || index >= MonthEx.DATECOUNT)
throw new Exception("Invalid index while calling MyCalendar.GetRectByIndex!");
int width = _control.Width / 7;
int height = _control.Height / 6;
int x = (index % 7) * width;
int y = (index / 7) * height;
return new Rectangle(x + 1, y + 1, width - 1, height - 1);
}
public int GetIndexByDate(DateTime date)
{
for (int i = 0; i < MonthEx.DATECOUNT; i++)
{
if (date.Date == _mymonth.Dates[i].date)
return i;
}
return -1;
}
public void SetImage(DateTime date, Image img,bool update)
{
if (img == null)
_hash.Remove(date.Date);
else
{
_hash.Remove(date.Date);
_hash.Add(date.Date, img);
}
if (update == true)
{
int index = GetIndexByDate(date);
if (index >= 0)
{
_control.Invalidate(GetRectByIndex(index));
_control.Update();
}
}
}
public Image GetImage(DateTime date)
{
if (_hash.ContainsKey(date.Date))
return (Image)_hash[date.Date];
return null;
}
public void ClearImage()
{
_hash.Clear();
}
public DateTime[] GetAllDates()
{
MonthEx.MyDate[] all = _mymonth.Dates;
DateTime[] dts = new DateTime[MonthEx.DATECOUNT];
for (int i = 0; i < MonthEx.DATECOUNT; i++)
{
dts[i] = all[i].date;
}
return dts;
}
public DateTime GetSelectedDate()
{
if (this._selected < 0 || this._selected >= MonthEx.DATECOUNT)
return new DateTime(_mymonth.Year, _mymonth.Month, 1);
else
return _mymonth.Dates[_selected].date;
}
public void OnKeyDown(System.Windows.Forms.Keys key)
{
if(key == System.Windows.Forms.Keys.Enter)
{
if(_selected >= 0)
((IMyCalChanged)(_control.Parent)).DoImageClicked(_mymonth.Dates[_selected].date,GetImage(_mymonth.Dates[_selected].date));
return;
}
int new_sel;
if (key == System.Windows.Forms.Keys.Up)
{
new_sel = _selected - 7;
if (new_sel < 0)
new_sel = 0;
}
else if (key == System.Windows.Forms.Keys.Down)
{
new_sel = _selected + 7;
if (new_sel > MonthEx .DATECOUNT - 1)
new_sel = MonthEx .DATECOUNT - 1;
}
else if (key == System.Windows.Forms.Keys.Left)
{
new_sel = _selected - 1;
if (new_sel < 0)
new_sel = 0;
}
else if (key == System.Windows.Forms.Keys.Right)
{
new_sel = _selected + 1;
if (new_sel > MonthEx .DATECOUNT - 1)
new_sel = MonthEx .DATECOUNT - 1;
}
else
{
return;
}
if (new_sel == _selected)
return;
int old_sel = _selected;
_selected = new_sel;
if (old_sel >= 0)
{
_control.Invalidate(GetRectByIndex(old_sel));
_control.Update();
}
_control.Invalidate(GetRectByIndex(_selected));
if (_mymonth.Dates[_selected].month == MonthEx.IN_WHICH_MONTH.IN_PREV_MONTH)
AdvanceMonth(false);
else if (_mymonth.Dates[_selected].month == MonthEx.IN_WHICH_MONTH.IN_NEXT_MONTH)
AdvanceMonth(true);
else
((IMyCalChanged)(_control.Parent)).DoSelChanged(_mymonth.Dates[_selected].date, _selected);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -