1. 달력의 비어있는 날짜 컨트롤
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using Systehttp://m.Threading.Tasks;
using Systehttp://m.Windows.Forms;
namespace CjControls
{
/// <summary>
/// 빈 날짜를 표시하는 컨트롤
/// </summary>
public partial class CjBlank : UserControl
{
/// <summary>
/// 생성자
/// </summary>
public CjBlank()
{
InitializeComponent();
}
}
}
2. 날짜 컨트롤
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Systehttp://m.ComponentModel.Design;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using Systehttp://m.Reflection.Emit;
using System.Text;
using Systehttp://m.Threading.Tasks;
using Systehttp://m.Windows.Forms;
namespace CjControls
{
public partial class CjDay : UserControl
{
#region attributes
/// <summary>
/// 선택되었는지 여부
/// </summary>
private bool m_bSelected = false;
[Browsable(true)]
[Description("선택되었는지 여부")]
[DefaultValue(false)]
public bool Selected
{
get { return m_bSelected; }
set
{
if (value)
{
m_bSelected = true;
this.BackColor = this.m_selectedColor;
this.ForeColor = this.m_selectedTxtColor;
}
else
{
m_bSelected = false;
m_nIndex = -1;
m_nMethod = -1;
this.BackColor = this.m_bkColor;
this.ForeColor = this.m_txtColor;
}
this.Invalidate();
}
}
/// <summary>
/// 컨트롤의 외곽라인의 존재여부
/// </summary>
private bool m_bOutline = false;
[Browsable(true)]
[Description("컨트롤의 외곽라인의 존재여부")]
public bool Outline
{
get { return m_bOutline; }
set
{
if (value != m_bOutline)
{
m_bOutline = value;
this.Invalidate();
}
}
}
/// <summary>
/// 선택되지 않은 상태의 배경색
/// </summary>
private Color m_bkColor = SystemColors.Control;
[Browsable(true)]
[Description("선택되지 않은 상태의 배경색")]
public Color BkColor
{
get { return m_bkColor; }
set
{
if (value != m_bkColor)
{
m_bkColor = value;
this.Invalidate();
}
}
}
/// <summary>
/// 선택된 상태의 배경색
/// </summary>
private Color m_selectedColor = SystemColors.ActiveCaption;
[Browsable(true)]
[Description("선택된 상태의 배경색")]
public Color SelectedColor
{
get { return m_selectedColor; }
set
{
if (value != m_selectedColor)
{
m_selectedColor = value;
this.Invalidate();
}
}
}
/// <summary>
/// 선택되지 않은 상태의 글자색
/// </summary>
private Color m_txtColor = SystemColors.ControlText;
[Browsable(true)]
[Description("선택되지 않은 상태의 글자색")]
public Color TxtColor
{
get { return m_txtColor; }
set
{
if (value != m_txtColor)
{
m_txtColor = value;
this.Invalidate();
}
}
}
/// <summary>
/// 선택된 상태의 글자색
/// </summary>
private Color m_selectedTxtColor = SystemColors.ControlText;
[Browsable(true)]
[Description("선택된 상태의 글자색")]
public Color SelectedTxtColor
{
get { return m_selectedTxtColor; }
set
{
if (value != m_selectedTxtColor)
{
m_selectedTxtColor = value;
this.Invalidate();
}
}
}
/// <summary>
/// 컨트롤의 외곽라인의 색상
/// </summary>
private Color m_outlineColor = SystemColors.ButtonShadow;
[Browsable(true)]
[Description("컨트롤의 외곽라인의 색상")]
public Color OutlineColor
{
get { return m_outlineColor; }
set
{
if (value != m_outlineColor)
{
m_outlineColor = value;
this.Invalidate();
}
}
}
/// <summary>
/// 선택된 날짜 그룹의 순번 (zero-based)
/// - -1이면 선택되지 않음.
/// - -1이 아니면 선택됨
/// </summary>
private int m_nIndex = -1;
[Browsable(true)]
[Description("선택된 날짜 그룹의 순번 (zero-based)")]
[DefaultValue(-1)]
public int Index
{
get { return m_nIndex; }
set { m_nIndex = value; }
}
/// <summary>
/// 선택 유형 (default=0, 0=연속형, 1=단일형)
/// </summary>
/// <remarks>
/// - 0 = 연속된 날짜로 구성된 그룹에 속함
/// - 1 = 낱개로 구성된 날짜의 그룹에 속함
/// </remarks>
private int m_nMethod = -1;
[Browsable(true)]
[Description("선택 유형 (-1=선택안됨, 0=연속형, 1=단일형)")]
[DefaultValue(-1)]
public int Method
{
get { return m_nMethod; }
set { m_nMethod = value; }
}
/// <summary>
/// 년도 (1~9999)
/// </summary>
private int m_nYear = 0;
[Browsable(true)]
[Description("년도 (1~9999)")]
[DefaultValue(0)]
public int Year
{
get { return m_nYear; }
set
{
m_nYear = value;
if (m_nYear > 0 && m_nMonth > 0 && m_nDay > 0)
{
m_Date = new DateTime(m_nYear, m_nMonth, m_nDay);
m_dateStr = $"{m_nYear.ToString("D4")}{m_nMonth.ToString("D2")}{m_nDay.ToString("D2")}";
WriteDay();
}
}
}
/// <summary>
/// 월 (1~12)
/// </summary>
private int m_nMonth = 0;
[Browsable(true)]
[Description("월 (1~12)")]
[DefaultValue(0)]
public int Month
{
get { return m_nMonth; }
set
{
m_nMonth = value;
if (m_nYear > 0 && m_nMonth > 0 && m_nDay > 0)
{
m_Date = new DateTime(m_nYear, m_nMonth, m_nDay);
m_dateStr = $"{m_nYear.ToString("D4")}{m_nMonth.ToString("D2")}{m_nDay.ToString("D2")}";
WriteDay();
}
}
}
/// <summary>
/// 일 (1~31)
/// </summary>
private int m_nDay = 0;
[Browsable(true)]
[Description("일 (1~31)")]
[DefaultValue(0)]
public int Day
{
get { return m_nDay; }
set
{
m_nDay = value;
if (m_nYear > 0 && m_nMonth > 0 && m_nDay > 0)
{
m_Date = new DateTime(m_nYear, m_nMonth, m_nDay);
m_dateStr = $"{m_nYear.ToString("D4")}{m_nMonth.ToString("D2")}{m_nDay.ToString("D2")}";
WriteDay();
}
}
}
/// <summary>
/// 날짜
/// </summary>
private DateTime m_Date = DateTime.MinValue;
[Browsable(true)]
[Description("날짜")]
[DefaultValue(0)]
public DateTime Date
{
get { return m_Date; }
set
{
try
{
if (value != DateTime.MinValue && value != DateTime.MaxValue)
{
Year = value.Year;
Month = value.Month;
Day = value.Day;
m_Date = value;
m_dateStr = $"{m_nYear.ToString("D4")}{m_nMonth.ToString("D2")}{m_nDay.ToString("D2")}";
WriteDay();
}
else
m_Date = DateTime.MinValue;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
/// <summary>
/// 날짜 문자열 (yyyyMMdd)
/// </summary>
private string m_dateStr = "";
[Browsable(true)]
[Description("날짜 문자열 (yyyyMMdd)")]
[DefaultValue(0)]
public string DateStr
{
get { return m_dateStr; }
set
{
if (!string.IsNullOrWhiteSpace(value) && value.Length >= 8
&& DateTime.TryParseExact(value, "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dt))
{
m_dateStr = value;
m_Date = dt;
m_nYear = dt.Year;
m_nMonth = dt.Month;
m_nDay = dt.Day;
WriteDay();
}
else
{
Debug.WriteLine($"잘못된 날짜({value})를 DateStr에 대입했습니다.");
}
}
}
#endregion
#region 생성자
/// <summary>
/// 생성자
/// </summary>
public CjDay()
{
InitializeComponent();
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="year">년 (1~9999)</param>
/// <param name="month">월 (1~12)</param>
/// <param name="day">일 (1~31)</param>
/// <param name="selected">선택되었는지 여부 (default=false)</param>
/// <param name="bOutline">외곽선의 존재여부</param>
public CjDay(int year, int month, int day, bool selected = false, bool bOutline = false)
{
InitializeComponent();
Initialize(year, month, day, selected, bOutline);
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="dt">날짜</param>
/// <param name="selected">선택되었는지 여부 (default=false)</param>
/// <param name="bOutline">외곽선의 존재여부</param>
public CjDay(DateTime dt, bool selected = false, bool bOutline = false)
{
InitializeComponent();
Initialize(dt, selected, bOutline);
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="dtStr">날짜</param>
/// <param name="selected">선택되었는지 여부 (default=false)</param>
/// <param name="bOutline">외곽선의 존재여부</param>
public CjDay(string dtStr, bool selected = false, bool bOutline = false)
{
InitializeComponent();
Initialize(dtStr, selected, bOutline);
}
#endregion
#region 컨트롤 이벤트
/// <summary>
/// WM_PAINT 메시지 이벤트
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
if (m_bOutline)
ControlPaint.DrawBorder(e.Graphics, ClientRectangle, m_outlineColor, ButtonBorderStyle.Solid);
if (m_bSelected)
{
LblDay.BackColor = m_selectedColor;
LblDay.ForeColor = m_selectedTxtColor;
}
else
{
LblDay.BackColor = m_bkColor;
LblDay.ForeColor = m_txtColor;
}
//using (Graphics g = e.Graphics)
//{
// Brush bs = new SolidBrush(m_bSelected ? m_selectedColor : m_bkColor);
// Rectangle rc = ClientRectangle;
// g.FillRectangle(bs, rc);
// g.DrawString(DateStr, this.Font, bs, rc);
//}
}
#endregion
#region 외부 함수
/// <summary>
/// 날짜 초기화하기
/// </summary>
/// <param name="year">년 (1~9999)</param>
/// <param name="month">월 (1~12)</param>
/// <param name="day">일 (1~31)</param>
/// <param name="selected">선택되었는지 여부 (default=false)</param>
/// <param name="bOutline">외곽선의 존재여부</param>
/// <returns>성공여부</returns>
public bool Initialize(int year, int month, int day, bool selected = false, bool bOutline = false)
{
m_bSelected = selected;
m_bOutline = bOutline;
if (0 < year && year < DateTime.MaxValue.Year
&& 0 < month && month < 12
&& 0 < day && day < DateTime.DaysInMonth(year, month))
{
m_Date = new DateTime(year, month, day);
return true;
}
Debug.WriteLine($"잘못된 날짜 매개변수({year}년, {month}월 {day}일) 입니다.");
return false;
}
/// <summary>
/// 날짜 초기화하기
/// </summary>
/// <param name="dt">날짜</param>
/// <param name="selected">선택되었는지 여부 (default=false)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
/// <returns>성공여부</returns>
public bool Initialize(DateTime dt, bool selected = false, bool bOutline = false)
{
m_bSelected = selected;
m_bOutline = bOutline;
if (dt != DateTime.MaxValue && dt != DateTime.MinValue)
{
m_Date = dt;
return true;
}
Debug.WriteLine($"잘못된 날짜 매개변수({dt}) 입니다.");
return false;
}
/// <summary>
/// 날짜 초기화하기
/// </summary>
/// <param name="dtStr">날짜 (yyyyMMdd)</param>
/// <param name="selected">선택되었는지 여부 (default=false)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
/// <returns>성공여부</returns>
public bool Initialize(string dtStr, bool selected = false, bool bOutline = false)
{
m_bSelected = selected;
m_bOutline = bOutline;
if (!string.IsNullOrWhiteSpace(dtStr) && dtStr.Length >= 8
&& DateTime.TryParseExact(dtStr, "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dt))
{
m_Date = dt;
return true;
}
Debug.WriteLine($"잘못된 날짜 매개변수({dtStr}) 입니다.");
return false;
}
/// <summary>
/// 날짜에 일수 더하기
/// </summary>
/// <param name="days">일수</param>
public CjDay AddDays(int days)
{
if (this.Date != DateTime.MinValue && this.Date != DateTime.MaxValue)
return new CjDay(this.Date.AddDays(days));
return this;
}
/// <summary>
/// 날짜에 월수 더하기
/// </summary>
/// <param name="months">월수</param>
public CjDay AddMonths(int months)
{
if (this.Date != DateTime.MinValue && this.Date != DateTime.MaxValue)
return new CjDay(this.Date.AddMonths(months));
return this;
}
/// <summary>
/// 날짜에 년수 더하기
/// </summary>
/// <param name="years">년수</param>
public CjDay AddYears(int years)
{
if (this.Date != DateTime.MinValue && this.Date != DateTime.MaxValue)
return new CjDay(this.Date.AddYears(years));
return this;
}
/// <summary>
/// 날짜를 컨트롤에 출력한다.
/// </summary>
public void WriteDay()
{
if (this.InvokeRequired)
{
this.Invoke(new EventHandler(delegate
{
LblDay.Text = m_nDay.ToString("D2");
}));
}
else
LblDay.Text = m_nDay.ToString("D2");
}
#endregion
}
}
3. 요일 표시 컨트롤
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using Systehttp://m.Threading.Tasks;
using Systehttp://m.Windows.Forms;
namespace CjControls
{
/// <summary>
/// 요일을 표시하는 컨트롤
/// </summary>
public partial class CjWeek : UserControl
{
#region attributes
/// <summary>
/// 요일 (0=일, 1=월, ..., 6=토)
/// </summary>
private DayOfWeek m_nWeek;
[Browsable(true)]
[Description("요일 (0=일, 1=월, ..., 6=토)")]
public DayOfWeek Week
{
get { return m_nWeek; }
set
{
if (DayOfWeek.Sunday <= value && value <= DayOfWeek.Saturday)
m_nWeek = value;
if (this.InvokeRequired)
{
this.Invoke(new EventHandler(delegate
{
LblWeek.Text = WeekStr;
}));
}
else
LblWeek.Text = WeekStr;
}
}
/// <summary>
/// 요일 문자열
/// </summary>
[Browsable(true)]
[Description("요일 (0=일, 1=월, ..., 6=토)")]
public string WeekStr
{
get
{
if (m_nWeek == DayOfWeek.Monday)
return "월";
else if (m_nWeek == DayOfWeek.Tuesday)
return "화";
else if (m_nWeek == DayOfWeek.Wednesday)
return "수";
else if (m_nWeek == DayOfWeek.Thursday)
return "목";
else if (m_nWeek == DayOfWeek.Friday)
return "금";
else if (m_nWeek == DayOfWeek.Saturday)
return "토";
else if (m_nWeek == DayOfWeek.Sunday)
return "일";
else
return "";
}
}
/// <summary>
/// 컨트롤의 외곽라인의 존재여부
/// </summary>
private bool m_bOutline = false;
[Browsable(true)]
[Description("컨트롤의 외곽라인의 존재여부")]
public bool Outline
{
get { return m_bOutline; }
set
{
if (value != m_bOutline)
{
m_bOutline = value;
this.Invalidate();
}
}
}
/// <summary>
/// 컨트롤의 외곽라인의 색상
/// </summary>
private Color m_outlineColor = SystemColors.ButtonShadow;
[Browsable(true)]
[Description("컨트롤의 외곽라인의 색상")]
public Color OutlineColor
{
get { return m_outlineColor; }
set
{
if (value != m_outlineColor)
{
m_outlineColor = value;
this.Invalidate();
}
}
}
/// <summary>
/// 선택되지 않은 상태의 배경색
/// </summary>
private Color m_bkColor = SystemColors.Control;
[Browsable(true)]
[Description("선택되지 않은 상태의 배경색")]
public Color BkColor
{
get { return m_bkColor; }
set
{
if (value != m_bkColor)
{
m_bkColor = value;
if (this.InvokeRequired)
{
this.Invoke(new EventHandler(delegate
{
LblWeek.BackColor = m_bkColor;
}));
}
else
LblWeek.BackColor = m_bkColor;
}
}
}
/// <summary>
/// 선택되지 않은 상태의 글자색
/// </summary>
private Color m_txtColor = SystemColors.ControlText;
[Browsable(true)]
[Description("선택되지 않은 상태의 글자색")]
public Color TxtColor
{
get { return m_txtColor; }
set
{
if (value != m_txtColor)
{
m_txtColor = value;
if (this.InvokeRequired)
{
this.Invoke(new EventHandler(delegate
{
LblWeek.ForeColor = m_txtColor;
}));
}
else
LblWeek.ForeColor = m_txtColor;
}
}
}
#endregion
#region 생성자
/// <summary>
/// 생성자
/// </summary>
public CjWeek()
{
InitializeComponent();
Week = DayOfWeek.Sunday;
}
#endregion
#region 컨트롤 이벤트
/// <summary>
/// WM_PAINT 메시지 이벤트
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
if (m_bOutline)
ControlPaint.DrawBorder(e.Graphics, ClientRectangle, m_outlineColor, ButtonBorderStyle.Solid);
}
#endregion
}
}
4. 달력
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Systehttp://m.ComponentModel.Design;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using Systehttp://m.Threading.Tasks;
using Systehttp://m.Windows.Forms;
namespace CjControls
{
/// <summary>
/// 단일 달력 컨트롤
/// </summary>
//[Designer("Systehttp://m.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class CjCalendarUnit : UserControl
{
#region attributes
/// <summary>
/// 달력 순번 (zero-based)
/// </summary>
private int m_nIndex = 0;
[Category("CjCalendarUnit")]
[Browsable(false)]
[Description("달력 순번")]
public int Index
{
get { return m_nIndex; }
set
{
m_nIndex = value;
}
}
/// <summary>
/// 달력이 위치한 행번호 (zero-based)
/// </summary>
private int m_nRow = 0;
[Category("CjCalendarUnit")]
[Browsable(false)]
[Description("달력이 위치한 행번호")]
public int Row
{
get { return m_nRow; }
set
{
m_nRow = value;
}
}
/// <summary>
/// 달력이 위치한 열번호 (zero-based)
/// </summary>
private int m_nColumn = 0;
[Category("CjCalendarUnit")]
[Browsable(false)]
[Description("달력이 위치한 열번호")]
public int Column
{
get { return m_nColumn; }
set
{
m_nColumn = value;
}
}
/// <summary>
/// 컨트롤의 외곽라인의 존재여부
/// </summary>
private bool m_bOutline = true;
[Category("CjCalendarUnit")]
[Browsable(true)]
[Description("컨트롤의 외곽라인의 존재여부")]
public bool Outline
{
get { return m_bOutline; }
set
{
m_bOutline = value;
this.Invalidate();
}
}
/// <summary>
/// 컨트롤의 외곽라인의 색상
/// </summary>
private Color m_outlineColor = SystemColors.ButtonShadow;
[Category("CjCalendarUnit")]
[Browsable(true)]
[Description("선택된 상태의 글자색")]
public Color OutlineColor
{
get { return m_outlineColor; }
set
{
m_outlineColor = value;
this.Invalidate();
}
}
/// <summary>
/// 날짜와 날짜 사이의 가로 간격 (default=0)
/// </summary>
private int m_xSpace = 0;
[Category("CjCalendarUnit")]
[Browsable(true)]
[Description("날짜와 날짜 사이의 가로 간격")]
public int XSpace
{
get { return (int)m_xSpace; }
set
{
m_xSpace = value;
this.Invalidate();
}
}
/// <summary>
/// 날짜와 날짜 사이의 세로 간격 (default=0)
/// </summary>
private int m_ySpace = 0;
[Category("CjCalendarUnit")]
[Browsable(true)]
[Description("날짜와 날짜 사이의 세로 간격")]
public int YSpace
{
get { return (int)m_ySpace; }
set
{
m_ySpace = value;
this.Invalidate();
}
}
/// <summary>
/// 현재 년도 (1~9999)
/// </summary>
private int m_nYear = DateTime.Now.Year;
[Category("CjCalendarUnit")]
[Browsable(true)]
[Description("년도 (1~9999)")]
public int Year
{
get { return m_nYear; }
set
{
m_nYear = value;
if (m_nYear > 0 && m_nMonth > 0)
{
m_strMonth = string.Format("{0:D4}{1:D2}", m_nYear, m_nMonth);
}
}
}
/// <summary>
/// 현재 월 (1~12)
/// </summary>
private int m_nMonth = DateTime.Now.Month;
[Category("CjCalendarUnit")]
[Browsable(true)]
[Description("월 (1~12)")]
public int Month
{
get { return m_nMonth; }
set
{
m_nMonth = value;
if (m_nYear > 0 && m_nMonth > 0)
{
m_strMonth = string.Format("{0:D4}{1:D2}", m_nYear, m_nMonth);
}
}
}
/// <summary>
/// 현재 달력의 년월 (yyyyMM)
/// </summary>
private string m_strMonth = DateTime.Now.ToString("yyyyMM");
[Category("CjCalendarUnit")]
[Browsable(true)]
[Description("달력의 년월 (yyyyMM)")]
public string MonthString
{
get
{
if (string.IsNullOrWhiteSpace(m_strMonth))
return DateTime.Now.ToString("yyyyMM");
else
return m_strMonth;
}
set
{
if (!string.IsNullOrWhiteSpace(value) && value.Length >= 6
&& DateTime.TryParseExact(value.Substring(0, 6) + "01", "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dt))
{
Year = dt.Year;
Month = dt.Month;
m_strMonth = value;
}
else
Debug.WriteLine($"잘못된 년월({value})을 MonthString에 대입했습니다.");
}
}
/// <summary>
/// 달력 생성에 성공했는지 여부
/// </summary>
public bool m_bSuccessed = false;
[Category("CjCalendarUnit")]
[Browsable(false)]
[Description("달력 생성에 성공했는지 여부")]
public bool Successed { get { return m_bSuccessed; } }
#endregion
#region 생성자
/// <summary>
/// 생성자
/// </summary>
/// <param name="index">달력 순번 (zero-based)</param>
/// <remarks>달력생성에 실패하면 순번은 0이 됨</remarks>
public CjCalendarUnit(int index = 0)
{
InitializeComponent();
if (Initialize(DateTime.Now.Year, DateTime.Now.Month))
if (Create(Year, Month))
{
m_nIndex = index;
m_bSuccessed = true;
}
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="index">달력 순번 (zero-based)</param>
/// <param name="dtStr">년월 (yyyyMM)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
/// <remarks>달력생성에 실패하면 순번은 0이 됨</remarks>
public CjCalendarUnit(int index, string dtStr, bool bOutline = false)
{
InitializeComponent();
if (Initialize(dtStr, bOutline))
if (Create(Year, Month))
{
m_nIndex = index;
m_bSuccessed = true;
}
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="index">달력 순번 (zero-based)</param>
/// <param name="year">년 (1~9999)</param>
/// <param name="month">월 (1~12)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
/// <remarks>달력생성에 실패하면 순번은 0이 됨</remarks>
public CjCalendarUnit(int index, int year, int month, bool bOutline = false)
{
InitializeComponent();
m_bSuccessed = Initialize(year, month, bOutline);
m_bSuccessed |= Create(Year, Month);
if (m_bSuccessed)
m_nIndex = index;
}
#endregion
#region 컨트롤 이벤트
/// <summary>
/// WM_PAINT 메시지 이벤트
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
if (m_bOutline)
ControlPaint.DrawBorder(e.Graphics, ClientRectangle, m_outlineColor, ButtonBorderStyle.Solid);
//using (Graphics g = e.Graphics)
//{
// if (SelectionDates != null && SelectionDates.Count > 0)
// foreach (CjSelectionDates v in SelectionDates)
// {
// if (v.Method == 1)
// {
// if (v.Days != null && v.Days.Count > 0)
// foreach (CjDay vv in v.Days)
// {
// vv.Selected = true;
// }
// }
// else
// {
// //CjDay st = v.Start <= v.End ? v.Start : v.End;
// //CjDay et = v.Start <= v.End ? v.End : v.Start;
// //for (; st <= et; st = st.AddDays(1))
// //{
// // st.Selected = true;
// //}
// }
// }
//}
}
#endregion
#region 외부 함수
/// <summary>
/// 달력 초기화하기
/// </summary>
/// <param name="year">년 (1~9999)</param>
/// <param name="month">월 (1~12)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
/// <returns>성공여부</returns>
public bool Initialize(int year, int month, bool bOutline = false)
{
m_bOutline = bOutline;
if (0 < year && year < DateTime.MaxValue.Year
&& 0 < month && month < 12
&& DateTime.TryParseExact($"{year.ToString("D4")}{month.ToString("D2")}01", "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dt))
{
m_nYear = year;
m_nMonth = month;
m_strMonth = $"{year.ToString("D4")}{month.ToString("D2")}";
return true;
}
Debug.WriteLine($"잘못된 날짜 매개변수({year}년, {month}월) 입니다.");
return false;
}
/// <summary>
/// 달력 초기화하기
/// </summary>
/// <param name="dtStr">년월 (yyyyMM)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
/// <returns>성공여부</returns>
public bool Initialize(string dtStr, bool bOutline = false)
{
m_bOutline = bOutline;
DateTime dt;
if ((dtStr.Length >= 8 && DateTime.TryParseExact(dtStr, "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out dt))
|| (dtStr.Length >= 6 && DateTime.TryParseExact(dtStr.Substring(0, 6) + "01", "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out dt)))
{
m_nYear = dt.Year;
m_nMonth = dt.Month;
m_strMonth = dt.ToString("yyyyMM");
return true;
}
Debug.WriteLine($"잘못된 년월 매개변수({dtStr}) 입니다.");
return false;
}
/// <summary>
/// 달력 생성하기
/// </summary>
/// <param name="year">년 (1~9999)</param>
/// <param name="month">월 (1~12)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
/// <returns>성공여부</returns>
public bool Create(int year, int month, bool bOutline = false)
{
try
{
PnlBody.Controls.Clear();
return Create($"{year.ToString("D4")}{month.ToString("D2")}", bOutline);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return false;
}
/// <summary>
/// 달력 생성하기
/// </summary>
/// <param name="dateStr">생성할 달력의 년월(yyyyMM 또는 yyyyMMdd)</param>
/// <param name="bOutline">외관경계선의 존재 여부</param>
/// <returns>성공여부</returns>
public bool Create(string dateStr, bool bOutline = false)
{
try
{
if (string.IsNullOrWhiteSpace(dateStr) || dateStr.Length < 6)
return false;
DateTime dt;
if ((dateStr.Length >= 8 && !DateTime.TryParseExact(dateStr, "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out dt))
|| !DateTime.TryParseExact(dateStr.Substring(0, 6) + "01", "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out dt))
{
Debug.WriteLine($"달력생성 오류: 잘못된 날짜 매개변수 ({dateStr})");
return false;
}
Size daySize = new Size(40, 20);
int wi = 0, hi = 0;
int x = 0;
int y = 0;
int tabIndex = 0;
int day = 1;
int c, r = 0;
dt = new DateTime(m_nYear, m_nMonth, day);
m_nYear = dt.Year;
m_nMonth = dt.Month;
m_strMonth = dt.ToString("yyyyMM");
#region 년월 출력
if (this.InvokeRequired)
{
this.Invoke(new EventHandler(delegate
{
LblTitle.Text = string.Format("{0:D4}년 {1:D2}월", m_nYear, m_nMonth);
}));
}
else
LblTitle.Text = string.Format("{0:D4}년 {1:D2}월", m_nYear, m_nMonth);
hi += LblTitle.Height;
#endregion
#region 요일 출력
for (c = 0; c < 7; ++c)
{
CjWeek cjWeek = new CjWeek();
cjWeek.BkColor = System.Drawing.SystemColors.Control;
cjWeek.Font = new Systehttp://m.Drawing.Font("바탕체", 10F, System.Drawing.FontStyle.Regular, Systehttp://m.Drawing.GraphicsUnit.Point, ((byte)(129)));
cjWeek.Location = new Systehttp://m.Drawing.Point(x, y);
cjWeek.MinimumSize = daySize;
cjWeek.Name = string.Format("cjWeek{0:D2}", c + 1);
cjWeek.Outline = false;
cjWeek.OutlineColor = System.Drawing.SystemColors.ButtonShadow;
cjWeek.Size = daySize;
cjWeek.TabIndex = tabIndex;
cjWeek.TxtColor = System.Drawing.SystemColors.ControlText;
cjWeek.Week = (System.DayOfWeek)c;
cjWeek.Click += OnClickWeeks;
PnlBody.Controls.Add(cjWeek);
x += daySize.Width;
}
y += daySize.Height;
#endregion
#region 빈 날짜 출력
for (c = 0, x = 0; c < (int)dt.DayOfWeek; ++c)
{
CjBlank cjBlank = new CjBlank();
cjBlank.Font = new Systehttp://m.Drawing.Font("바탕체", 10F, System.Drawing.FontStyle.Regular, Systehttp://m.Drawing.GraphicsUnit.Point, ((byte)(129)));
cjBlank.Location = new Systehttp://m.Drawing.Point(x, y);
cjBlank.Margin = new Systehttp://m.Windows.Forms.Padding(4, 3, 4, 3);
cjBlank.MinimumSize = daySize;
cjBlank.Name = string.Format("cjBlank{0:D2}", c + 1);
cjBlank.Size = daySize;
cjBlank.TabIndex = ++tabIndex;
PnlBody.Controls.Add(cjBlank);
x += daySize.Width;
}
#endregion
#region 날짜 출력
for (int days = DateTime.DaysInMonth(m_nYear, m_nMonth); day <= days; )
{
for ( ; c < 7 && day <= days; ++c, ++day)
{
dt = new DateTime(m_nYear, m_nMonth, day);
CjDay cjDay = new CjDay();
cjDay.BackgroundImageLayout = Systehttp://m.Windows.Forms.ImageLayout.Stretch;
cjDay.BkColor = System.Drawing.SystemColors.Control;
cjDay.CausesValidation = false;
cjDay.DateStr = dt.ToString("yyyyMMdd");
cjDay.Font = new Systehttp://m.Drawing.Font("바탕체", 10F);
cjDay.Location = new Systehttp://m.Drawing.Point(x, y);
cjDay.MinimumSize = daySize;
cjDay.Name = string.Format("cjDay{0:D2}", dt.Day);
cjDay.Outline = false;
cjDay.OutlineColor = System.Drawing.SystemColors.ButtonShadow;
cjDay.SelectedColor = System.Drawing.SystemColors.ActiveCaption;
cjDay.SelectedTxtColor = System.Drawing.SystemColors.ControlText;
cjDay.Size = daySize;
cjDay.TabIndex = ++tabIndex;
cjDay.TxtColor = System.Drawing.SystemColors.ControlText;
cjDay.Click += OnClickDays;
PnlBody.Controls.Add(cjDay);
x += daySize.Width;
if (wi < x)
wi = x;
}
++r;
c = 0;
x = 0;
y += daySize.Height;
}
#endregion
hi += ((r < 6)? y + daySize.Height : y) + SystemInformation.FrameBorderSize.Height;
wi += SystemInformation.FrameBorderSize.Width;
this.Size = new Systehttp://m.Drawing.Size(wi, hi);
this.MinimumSize = this.Size;
return true;
}
catch (Exception ex)
{
Debug.WriteLine (ex.Message);
return false;
}
}
/// <summary>
/// 날짜를 클릭했을 때
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void OnClickDays(object sender, EventArgs e)
{
try
{
Debug.WriteLine($"{sender.ToString()}");
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
/// <summary>
/// 요일을 클릭했을 때
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void OnClickWeeks(object sender, EventArgs e)
{
try
{
Debug.WriteLine($"{sender.ToString()}");
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
#endregion
}
}
5. 다중 달력
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using Systehttp://m.Threading.Tasks;
using Systehttp://m.Windows.Forms;
using static Systehttp://m.Windows.Forms.VisualStyles.VisualStyleElement.Tab;
namespace CjControls
{
public partial class CjCalendars : UserControl
{
#region attributes
/// <summary>
/// 컨트롤의 외곽라인의 존재여부
/// </summary>
private bool m_bOutline = true;
[Category("CjCalendars")]
[Browsable(true)]
[Description("컨트롤의 외곽라인의 존재여부")]
public bool Outline
{
get { return m_bOutline; }
set
{
m_bOutline = value;
this.Invalidate();
}
}
/// <summary>
/// 컨트롤의 외곽라인의 색상
/// </summary>
private Color m_outlineColor = SystemColors.ButtonShadow;
[Category("CjCalendars")]
[Browsable(true)]
[Description("선택된 상태의 글자색")]
public Color OutlineColor
{
get { return m_outlineColor; }
set
{
m_outlineColor = value;
this.Invalidate();
}
}
/// <summary>
/// 날짜와 날짜 사이의 가로 간격 (default=0)
/// </summary>
private int m_xSpace = 0;
[Category("CjCalendars")]
[Browsable(true)]
[Description("날짜와 날짜 사이의 가로 간격")]
public int XSpace
{
get { return (int)m_xSpace; }
set
{
m_xSpace = value;
this.Invalidate();
}
}
/// <summary>
/// 날짜와 날짜 사이의 세로 간격 (default=0)
/// </summary>
private int m_ySpace = 0;
[Category("CjCalendars")]
[Browsable(true)]
[Description("날짜와 날짜 사이의 세로 간격")]
public int YSpace
{
get { return (int)m_ySpace; }
set
{
m_ySpace = value;
this.Invalidate();
}
}
/// <summary>
/// 현재 년도 (1~9999)
/// </summary>
private int m_nYear = DateTime.Now.Year;
[Category("CjCalendars")]
[Browsable(true)]
[Description("년도 (1~9999)")]
public int Year
{
get { return m_nYear; }
set
{
m_nYear = value;
if (m_nYear > 0 && m_nMonth > 0)
{
m_strMonth = string.Format("{0:D4}{1:D2}", m_nYear, m_nMonth);
}
}
}
/// <summary>
/// 현재 월 (1~12)
/// </summary>
private int m_nMonth = DateTime.Now.Month;
[Category("CjCalendars")]
[Browsable(true)]
[Description("월 (1~12)")]
public int Month
{
get { return m_nMonth; }
set
{
m_nMonth = value;
if (m_nYear > 0 && m_nMonth > 0)
{
m_strMonth = string.Format("{0:D4}{1:D2}", m_nYear, m_nMonth);
}
}
}
/// <summary>
/// 현재 달력의 년월 (yyyyMM)
/// </summary>
private string m_strMonth = DateTime.Now.ToString("yyyyMM");
[Category("CjCalendars")]
[Browsable(true)]
[Description("달력의 년월 (yyyyMM)")]
public string MonthString
{
get
{
if (string.IsNullOrWhiteSpace(m_strMonth))
return DateTime.Now.ToString("yyyyMM");
else
return m_strMonth;
}
set
{
if (!string.IsNullOrWhiteSpace(value) && value.Length >= 6
&& DateTime.TryParseExact(value.Substring(0, 6) + "01", "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dt))
{
Year = dt.Year;
Month = dt.Month;
m_strMonth = value;
}
else
Debug.WriteLine($"잘못된 년월({value})을 MonthString에 대입했습니다.");
}
}
/// <summary>
/// 선택된 날짜 목록
/// </summary>
private List<CjSelectionDates> m_SelectionDates = new List<CjSelectionDates>();
[Category("CjCalendars")]
[Browsable(false)]
[Description("선택된 날짜 목록")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public List<CjSelectionDates> SelectionDates
{
get
{
return m_SelectionDates;
}
set
{
if (value == null)
m_SelectionDates = new List<CjSelectionDates>();
else
m_SelectionDates = value;
}
}
/// <summary>
/// 선택된 날짜들로 화면에 표시해야할 달력(yyyyMM)들
/// </summary>
public List<string> MonthList
{
get
{
if (SelectionDates == null || SelectionDates.Count < 1)
return new List<string>();
else
{
List<string> list = new List<string>();
foreach (CjSelectionDates v in SelectionDates)
{
if (v.Method == 1)
{
list.AddRange((from CjDay vv in v.Days
let month = vv.Date.ToString("yyyyMM")
where !list.Contains(month)
orderby vv.Date
select month).Distinct().ToList());
}
else
{
for (DateTime st = v.Start.Date; st <= v.End.Date; st = st.AddMonths(1))
{
string month = st.ToString("yyyyMM");
if (!list.Contains(month))
list.Add(month);
}
}
}
return list.Distinct().ToList();
}
}
}
/// <summary>
/// 단위달력의 최소 폭
/// </summary>
private const int MinWidth = 292;
/// <summary>
/// 단위달력의 최소 높이
/// </summary>
private const int MinHight = 188;
/// <summary>
/// 단위달력의 폭
/// </summary>
private int m_nUnitWidth = 0;
[Category("CjCalendars")]
[Browsable(false)]
[Description("단위달력의 폭")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int UnitWidth
{
get { return m_nUnitWidth; }
set
{
m_nUnitWidth = value;
}
}
/// <summary>
/// 단위달력의 높이
/// </summary>
private int m_nUnitHeight = 0;
[Category("CjCalendars")]
[Browsable(false)]
[Description("단위달력의 높이")]
public int UnitHeight
{
get { return m_nUnitHeight; }
set
{
m_nUnitHeight = value;
}
}
/// <summary>
/// 행 갯수
/// </summary>
private int m_nRowCount = 1;
[Category("CjCalendars")]
[Browsable(false)]
[Description("행 갯수")]
public int RowCount
{
get { return m_nRowCount; }
set
{
m_nRowCount = value;
}
}
/// <summary>
/// 열 갯수
/// </summary>
private int m_nColCount = 1;
[Category("CjCalendars")]
[Browsable(false)]
[Description("열 갯수")]
public int ColCount
{
get { return m_nColCount; }
set
{
m_nColCount = value;
}
}
/// <summary>
/// 수정되었는지 여부
/// </summary>
private bool m_bMofidied = false;
[Category("CjCalendars")]
[Browsable(false)]
[Description("수정되었는지 여부")]
public bool IsModified
{
get { return m_bMofidied; }
set
{
m_bMofidied = value;
if (m_bMofidied)
{
Create(m_bOutline);
}
}
}
#endregion
#region 생성자
/// <summary>
/// 생성자
/// </summary>
public CjCalendars()
{
InitializeComponent();
try
{
if (this.DesignMode)
Create();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="dtStr">년월 (yyyyMM)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
public CjCalendars(List<CjSelectionDates> cjSelections, bool bOutline = false)
{
InitializeComponent();
try
{
if (cjSelections != null && cjSelections.Count > 0)
SelectionDates = cjSelections;
if (this.DesignMode)
Create();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
#endregion
#region 컨트롤 이벤트
/// <summary>
/// WM_PAINT 메시지 이벤트
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
if (m_bOutline)
ControlPaint.DrawBorder(e.Graphics, ClientRectangle, m_outlineColor, ButtonBorderStyle.Solid);
//using (Graphics g = e.Graphics)
//{
// if (SelectionDates != null && SelectionDates.Count > 0)
// foreach (CjSelectionDates v in SelectionDates)
// {
// if (v.Method == 1)
// {
// if (v.Days != null && v.Days.Count > 0)
// foreach (CjDay vv in v.Days)
// {
// vv.Selected = true;
// }
// }
// else
// {
// //CjDay st = v.Start <= v.End ? v.Start : v.End;
// //CjDay et = v.Start <= v.End ? v.End : v.Start;
// //for (; st <= et; st = st.AddDays(1))
// //{
// // st.Selected = true;
// //}
// }
// }
//}
}
#endregion
#region 내부함수
/// <summary>
/// 달력 행렬 설정하기
/// </summary>
private void SetLayoutCalendar()
{
#region 행렬 생성
if (this.MonthList.Count > 9)
{
m_nRowCount = 3;
m_nColCount = 4;
}
else if (this.MonthList.Count > 6)
{
m_nRowCount = 3;
m_nColCount = 3;
}
else if (this.MonthList.Count > 4)
{
m_nRowCount = 2;
m_nColCount = 3;
}
else if (this.MonthList.Count == 4)
{
m_nRowCount = 2;
m_nColCount = 2;
}
else if (this.MonthList.Count == 3)
{
m_nRowCount = 1;
m_nColCount = 3;
}
else if (this.MonthList.Count == 2)
{
m_nRowCount = 1;
m_nColCount = 2;
}
else
{
m_nRowCount = 1;
m_nColCount = 1;
}
#endregion
}
#endregion
#region 외부 함수
/// <summary>
/// 달력 생성하기
/// </summary>
/// <param name="bOutline">달력의 외곽라인이 있는지 여부 (default=false)</param>
/// <returns>생성된 달력의 갯수</returns>
public int Create(bool bOutline = false)
{
int countCalendars = 0;
try
{
SetLayoutCalendar();
int wi = MinWidth, hi = MinHight;
if (this.MonthList.Count > 0)
{
int idx = -1;
for (int r = 0; r < m_nRowCount; ++r)
{
for (int c = 0; c < m_nColCount; ++c)
{
++idx;
if (idx < this.MonthList.Count)
{
string v = this.MonthList[idx].ToString();
int year = Convert.ToInt32(v.Substring(0, 4));
int month = Convert.ToInt32(v.Substring(4, 2));
var unit = Create(idx, v, bOutline);
if (unit != null)
{
unit.Row = r;
unit.Column = c;
tblCalendars.Controls.Add(unit, c, r);
if (wi < unit.Width)
wi = unit.Width;
if (hi < unit.Height)
hi = unit.Height;
++countCalendars;
}
}
}
}
}
else
{
string dateStr = DateTime.Now.ToString("yyyyMMdd");
var unit = Create(0, dateStr, bOutline);
if (unit != null)
{
unit.Row = 0;
unit.Column = 0;
tblCalendars.Controls.Add(unit, 0, 0);
if (wi < unit.Width)
wi = unit.Width;
if (hi < unit.Height)
hi = unit.Height;
++countCalendars;
SelectionDates.Add(new CjSelectionDates(0, dateStr.Substring(0, 6)));
}
}
m_nUnitWidth = wi + SystemInformation.FrameBorderSize.Width * 2;
m_nUnitHeight = hi + SystemInformation.FrameBorderSize.Height * 2;
wi = m_nColCount * m_nUnitWidth + SystemInformation.FrameBorderSize.Width * 2;
hi = m_nRowCount * m_nUnitHeight + SystemInformation.FrameBorderSize.Height * 2;
this.Size = new Size(wi, hi);
//tblCalendars.Size = new Size(wi, hi);
this.tblCalendars.RowCount = m_nRowCount;
this.tblCalendars.ColumnCount = m_nColCount;
SetUnitSize(m_nUnitWidth, m_nUnitHeight);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return countCalendars;
}
/// <summary>
/// 달력 생성하기
/// </summary>
/// <param name="year">년 (1~9999)</param>
/// <param name="month">월 (1~12)</param>
/// <param name="bOutline">외곽라인이 있는지 여부 (default=false)</param>
/// <returns>성공여부</returns>
public CjCalendarUnit Create(int idx, int year, int month, bool bOutline = false)
{
try
{
return Create(idx, string.Format("{0:D4}{1:D2}", year, month), bOutline); ;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return null;
}
/// <summary>
/// 달력 생성하기
/// </summary>
/// <param name="idx">달력 순번(zero-based)</param>
/// <param name="dateStr">생성할 달력의 년월(yyyyMM 또는 yyyyMMdd)</param>
/// <param name="bOutline">외관경계선의 존재 여부</param>
/// <returns>성공여부</returns>
public CjCalendarUnit Create(int idx, string dateStr, bool bOutline = false)
{
try
{
DateTime dt;
if ((dateStr.Length >= 8 && !DateTime.TryParseExact(dateStr, "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out dt))
|| !DateTime.TryParseExact(dateStr.Substring(0, 6) + "01", "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out dt))
{
Debug.WriteLine($"달력생성 오류: 잘못된 날짜 매개변수 ({dateStr})");
return null;
}
CjCalendarUnit unit = new CjCalendarUnit(idx, dt.ToString("yyyyMMdd"), bOutline);
if (unit.Successed)
{
return unit;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return null;
}
/// <summary>
/// 단위달력의 크기 구하기
/// </summary>
/// <returns>Size</returns>
public Size GetUnitSize()
{
return new Size(UnitWidth, UnitHeight);
}
/// <summary>
/// 단위달력의 크기 설정하기
/// </summary>
/// <param name="wi">단위달력의 폭</param>
/// <param name="hi">단위달력의 높이</param>
public void SetUnitSize(int wi = MinWidth, int hi = MinHight)
{
try
{
m_nUnitWidth = wi + SystemInformation.FrameBorderSize.Width;
m_nUnitHeight = hi + SystemInformation.FrameBorderSize.Height;
if (this.tblCalendars.RowStyles.Count > 0)
{
for (int r = 0; r < this.tblCalendars.RowStyles.Count; ++r)
{
this.tblCalendars.RowStyles[r].SizeType = SizeType.Absolute;
this.tblCalendars.RowStyles[r].Height = m_nUnitHeight;
}
}
if (this.tblCalendars.ColumnStyles.Count > 0)
{
for (int c = 0; c < this.tblCalendars.ColumnStyles.Count; ++c)
{
this.tblCalendars.ColumnStyles[c].SizeType = SizeType.Absolute;
this.tblCalendars.ColumnStyles[c].Width = m_nUnitWidth;
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
/// <summary>
/// 선택된 날짜(기간)을 저장한다. 단, 주어진 인덱스를 가진 기존 데이터는 삭제한다.
/// </summary>
/// <param name="idx">선택된 날짜그룹의 인덱스</param>
/// <param name="startDate">선택시작일</param>
/// <param name="endDate">선택종료일</param>
public void SetSelectionDates(int idx, string startDate, string endDate)
{
try
{
DateTime st = DateTime.ParseExact(startDate, "yyyyMMdd", null);
DateTime et = DateTime.ParseExact(endDate, "yyyyMMdd", null);
/// 기존 인덱스를 가진 데이터를 삭제한다.
var lst = (from CjSelectionDates v in SelectionDates
where v.Index == idx
select v).ToList();
if (lst != null)
{
while (lst.Count > 0)
{
lst.Remove(lst.Last());
}
}
SelectionDates.Add(new CjSelectionDates(idx, st, et));
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
/// <summary>
/// 선택된 날짜(기간)을 저장한다. 단, 주어진 인덱스를 가진 기존 데이터는 삭제한다.
/// </summary>
/// <param name="idx">선택된 날짜그룹의 인덱스</param>
/// <param name="days">선택된 날짜들 (yyyyMMdd)</param>
public void SetSelectionDates(int idx, string[] days)
{
try
{
if (days == null || days.Count() < 1)
{
return;
}
/// 기존 인덱스를 가진 데이터를 삭제한다.
var lst = (from CjSelectionDates v in SelectionDates
where v.Index == idx
select v).ToList();
if (lst != null)
{
while (lst.Count > 0)
{
lst.Remove(lst.Last());
}
}
CjSelectionDates cjSelectionDates = new CjSelectionDates(idx, days.ToString());
cjSelectionDates.Method = 1;
SelectionDates.Add(cjSelectionDates);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
#endregion
#region 내부함수
/// <summary>
/// 날짜를 클릭했을 때
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnClickDays(object sender, EventArgs e)
{
try
{
Debug.WriteLine($"{sender.ToString()}");
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
#endregion
#region CjSelectionDates
/// <summary>
/// 선택된 날짜 그룹
/// </summary>
public class CjSelectionDates
{
#region attributes
/// <summary>
/// 선택된 날짜 그룹의 순번 (zero-based)
/// - -1이면 선택된 날짜가 없다.
/// - -1이 아니면 선택된 날짜가 있다.
/// </summary>
public int Index { get; set; } = -1;
/// <summary>
/// 선택된 날짜의 유형 (default=0)
/// </summary>
/// <remarks>
/// - 0 = 연결된 날짜로 구성된 그룹으로 시작날짜와 종료날짜가 있다.
/// - 1 = 낱개로 구성된 날짜의 그룹으로 시작날짜와 종료날짜가 없다.
/// </remarks>
public int Method { get; set; } = 0;
/// <summary>
/// 선택한 날짜 그룹의 시작날짜
/// </summary>
public CjDay Start { get; set; } = null;
/// <summary>
/// 선택한 날짜 그룹의 종료날짜
/// </summary>
public CjDay End { get; set; } = null;
/// <summary>
/// 개별 날짜 모음
/// </summary>
public List<CjDay> Days { get; set; } = new List<CjDay>();
#endregion
#region 생성자
/// <summary>
/// 생성자
/// </summary>
public CjSelectionDates()
{
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="idx">순번 (zero-based)</param>
/// <param name="year">선택된 년도</param>
/// <param name="month">선택된 월</param>
public CjSelectionDates(int idx, int year, int month)
{
DateTime today = new DateTime(year, month, 1);
if (idx >= 0 && today != DateTime.MinValue && today != DateTime.MaxValue)
{
Index = idx;
Method = 0;
this.Start = new CjDay(today);
this.End = new CjDay(today);
}
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="idx">순번 (zero-based)</param>
/// <param name="dateStr">선택된 날짜 문자열(yyyyMMdd)</param>
public CjSelectionDates(int idx, string dateStr)
{
try
{
if (!DateTime.TryParseExact(dateStr, "yyyyMMdd", null, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime today))
{
Debug.WriteLine("CjSelectionDates error: 올바르지않은 날짜 형태입니다." + dateStr);
return;
}
Index = (idx < 0 ? -1 : idx);
Method = 0;
this.Start = new CjDay(today);
this.End = new CjDay(today);
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="idx">순번 (zero-based)</param>
/// <param name="today">선택된 날짜</param>
public CjSelectionDates(int idx, DateTime today)
{
if (idx >= 0 && today != DateTime.MinValue && today != DateTime.MaxValue)
{
Index = idx;
Method = 0;
this.Start = new CjDay(today);
this.End = new CjDay(today);
}
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="idx">순번 (zero-based)</param>
/// <param name="start">선택된 시작날짜</param>
/// <param name="end">선택된 종료날짜</param>
public CjSelectionDates(int idx, DateTime start, DateTime end)
{
if (idx >= 0
&& start != DateTime.MinValue && start != DateTime.MaxValue
&& end != DateTime.MinValue && end != DateTime.MaxValue)
{
Index = idx;
Method = 0;
this.Start = (start <= end) ? new CjDay(start) : new CjDay(end);
this.End = (start <= end) ? new CjDay(end) : new CjDay(start);
}
else
Debug.WriteLine($"잘못된 매개변수: 순번={idx}, 시작날짜={start}, 종료날짜={end}");
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="idx">순번 (zero-based)</param>
/// <param name="days">선택된 날짜들(yyyyMM)</param>
public CjSelectionDates(int idx, List<string> days)
{
if (idx >= 0 && days != null && days.Count > 0)
{
Index = idx;
Method = 1;
if (Days == null)
Days = new List<CjDay>();
var lst = from string v in days orderby v select v;
foreach (string v in lst)
{
Days.Add(new CjDay(v));
}
}
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="idx">순번 (zero-based)</param>
/// <param name="days">선택된 날짜들</param>
public CjSelectionDates(int idx, List<DateTime> days)
{
if (idx >= 0 && days != null && days.Count > 0)
{
Index = idx;
Method = 1;
if (Days == null)
Days = new List<CjDay>();
var lst = from DateTime v in days orderby v select v;
foreach (DateTime v in lst)
{
Days.Add(new CjDay(v));
}
}
}
/// <summary>
/// 생성자
/// </summary>
/// <param name="idx">순번 (zero-based)</param>
/// <param name="days">선택된 날짜들</param>
public CjSelectionDates(int idx, List<CjDay> days)
{
if (idx >= 0 && days != null && days.Count > 0)
{
Index = idx;
Method = 1;
if (Days == null)
Days = new List<CjDay>();
var lst = from DateTime v in days orderby v select v;
foreach (DateTime v in lst)
{
Days.Add(new CjDay(v));
}
}
}
#endregion
/// <summary>
/// 선택된 달력 리스트
/// </summary>
public List<string> getMonthList()
{
List<string> rt = new List<string>();
if (Method == 0)
{
if (Start != null && End != null)
{
for (DateTime dt = Start.Date; dt <= End.Date; dt.AddMonths(1))
rt.Add(dt.ToString("yyyyMM"));
}
else if (Start != null)
{
rt.Add(Start.Date.ToString("yyyyMM"));
}
}
else
{
if (Days.Count > 0)
{
var lst = (from CjDay v in Days orderby v.Date select new DateTime(v.Year, v.Month, 1)).Distinct().ToList();
foreach (DateTime v in lst)
rt.Add(v.ToString("yyyyMM"));
}
}
return rt;
}
}
#endregion
}
}
예제:
'유용한 정보' 카테고리의 다른 글
[C#] DataGridView에서 DataSource 연동하는 방법 (0) | 2025.05.24 |
---|---|
[clr] Window Forms 컨트롤 라이브러리 MFC에서 사용하기 사용 (0) | 2025.05.06 |
[C#] DataGridView 자동 행 번호 생성하는 방법(예제) (0) | 2025.05.05 |
[C#] 사용자 정의 이벤트 등록 및 사용 예제 (0) | 2025.04.27 |
[C#] MonthCalendar 요일 클릭하기 (0) | 2025.04.24 |