C# 开发备忘录(自定义日历)

C#开发自定义备忘录(自制精美日历)(用VS开发的winForm应用程序)

目录

1 有关信息

2 程序截图

3 该程序尚未完成的功能/不足之处

4 资源下载

5 源代码

 5.1 项目结构

 5.2 注意事项

5.3 MemorandumUI

Program.cs

FormMain.cs

FormAdd.cs

FormDetail.cs

FormResetOwner.cs

Resources

5.4 MemoModel

MemoModel.cs

5.5 Tool

tool.cs

5.6 MemoDAL

MemoDAL.cs

5.7 MemoBLL

MemoBLL.cs


 

1 有关信息

  IDE:Microsoft Visual Studio 2012 ;

  数据库:Microsoft SQL Server 2012 ;

  架构:三层架构(DAL、BLL、Model) ;

  开发者:邓宇、曾敏慧、张莹 ;

 

2 程序截图

 

3 该程序尚未完成的功能/不足之处

  ①生肖的判断标准没有改成以农历年来判断;

  ②没有实现备忘录提醒功能,目前只能创建、删除、查看;

 

4 资源下载

https://download.csdn.net/download/qq_37027371/10931704

 

5 源代码

 5.1 项目结构

  该解决方案(应用程序)由五个项目组成:

  

 

  MemoBLL (业务逻辑层,其实该有的功能我们都写在DAL层里了,BLL其实没起到它的作用)

  MemoDAL (数据访问层)

  MemoModel (模型层)

  MemorandumUI (界面)

  Tool (辅助工具,例如得到某天的农历)

 

 5.2 注意事项

①数据库可以自己在本地创建,数据库命名为“memorandum”,表可以不用建,DAL中有自动建表的代码。

②因为项目中用到Json字符串,所以要导入Json工具,可以自己去网上下载并导入,导入成功会有这一行

 

5.3 MemorandumUI

Program.cs

using MemoModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tool;

namespace MemorandumUI
{
    static class Program
    {
        /// <summary> 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Application.Run(new FormMain());
        }
    }
}

FormMain.cs

using MemoModel;
using Memorandum;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tool;

namespace MemorandumUI
{
    public partial class FormMain : Form
    {
        /// <summary>控件的配置 属性
        /// </summary>
        Config config;
        
        /// <summary>备忘录事件列表
        /// </summary>
        List<MyEvent> events;
        /// <summary>此列表用于存放多选的备忘录事件的下标
        /// </summary>
        List<int> selectedEventsIndex;

        #region 控制无边框窗体的移动
        //using System.Runtime.InteropServices;
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        #endregion

        
        public FormMain()
        {
            InitializeComponent();
            config = new Config();

            config.initialItemPanel(panel_event.Width,panel_event.Height);//初始化事件项的大小

            events = new List<MyEvent>();
            selectedEventsIndex = new List<int>();

            #region 从本地导入用户名
            FileHelper fileHelper = new FileHelper();
            labelOwner.Text = fileHelper.readOwner();
            #endregion

            //Debug.WriteLine("flow panel 子控件个数: "+panel_calendar.Controls.Count);

            #region 给日历面板中的每个日期标签添加点击事件
            for (int i = 1; i < panel_calendar.Controls.Count; i++)
            {
                ((Label)panel_calendar.Controls[i]).Click += new EventHandler(label1_Click);
                //把日历中的字体变小一点,以防超出显示范围,显示不出来
                ((Label)panel_calendar.Controls[i]).Font = new System.Drawing.Font("Bahnschrift Condensed", 
                    12.5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            }
            #endregion

            jumpToToday();//跳到今天

            
            //panel_event.Controls.Add(createEventPanel());
            //panel_event.Controls.Add(createEventPanel());

            //panel_event.Controls.Clear();
            

            timer1.Start();//打开计时器,用来更新当前时间
        }

        #region 自定义可拖动状态栏
        //最小化 点击
        private void button1_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }


        //关闭 点击
        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        //拖动 按下
        private void panel3_MouseDown(object sender, MouseEventArgs e)
        {
            //常量
            int WM_SYSCOMMAND = 0x0112;

            //窗体移动
            int SC_MOVE = 0xF010;
            int HTCAPTION = 0x0002;

            ReleaseCapture();
            SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
        }

        #endregion


        //全年所有事件 点击按钮
        private void label_all_event_Click(object sender, EventArgs e)
        {
            if (config.isSelectedWholeYearEvent == false)
            {//尚未选中的时候,把它设置为选中
                label_whole_year_event.ForeColor = Color.DeepSkyBlue;
                config.isSelectedWholeYearEvent = true;

                events = selectYear(int.Parse(label_year.Text));
                resetEventPanel(events);
            }
            else {
                label_whole_year_event.ForeColor = Color.White;
                config.isSelectedWholeYearEvent = false;
                jumpToToday();
            }

        }
        
        //读取按钮 将txt文件读取成MyEvent类
        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            //fileDialog.Multiselect = true;
            fileDialog.Title = "请选择文件";
            fileDialog.Filter = "txt文件(*.txt)|*.txt|所有文件(*.*)|*.*";
            //fileDialog.Filter = "txt文件(*.txt)|*.txt";

            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                string file = fileDialog.FileName;
                FileHelper fileHelper = new FileHelper();
                List<MyEvent> list = fileHelper.read(file);
                MemoBLL.MemoBLL bll = new MemoBLL.MemoBLL();
                bll.addEvent(list);
                jumpToToday();
                MessageBox.Show("已选择文件:" + file, "选择文件提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }


        //导出按钮 将MyEvent类变成json字符串,保存到txt文件
        private void button3_Click(object sender, EventArgs e)
        {
            List<MyEvent> myEvents = new List<MyEvent>();
            MyEvent zy = new MyEvent("abc", "haha", "zy", "饭堂", DateTime.Parse("2018-11-26 22:00:00"), DateTime.Parse("2018-11-26 22:00:00"), DateTime.Parse("2018-11-26 22:00:00"), "1");
            myEvents.Add(zy);

            Debug.WriteLine("导出按钮: " + zy.getEventName());

            SaveFileDialog sf = new SaveFileDialog();
            sf.Title = "请选择文件";
            sf.Filter = "txt文件(*.txt)|*.txt|所有文件(*.*)|*.*";
            if (sf.ShowDialog() == DialogResult.OK)
            {
                string name = sf.FileName;
                FileHelper fileHelper = new FileHelper();
                fileHelper.save(events, selectedEventsIndex, name);
            }

        }

        //添加按钮
        private void btn_add_Click(object sender, EventArgs e)
        {
            DateTime nowTime = new DateTime(config.nowSelectedDay.Year,
                config.nowSelectedDay.Month, config.nowSelectedDay.Day,
                DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
            FormAdd formAdd = new FormAdd(this.Location, labelOwner.Text, nowTime);
            
            //Debug.WriteLine("主 添加 坐标:" + this.Location.X + " " + this.Location.Y);
            if (formAdd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                refreshEventPanel();
            }
        }

        #region  拖动实现数字加减 改变年和月

        
        /// <summary>年份拖动 按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label_year_MouseDown(object sender, MouseEventArgs e)
        {
            
            config.yearBeginMove = true;
            config.yearOriginalPointY = MousePosition.Y;
            config.lastY = config.yearOriginalPointY;
            config.lastFixedY = config.yearOriginalPointY;
            config.originalYear = int.Parse( ((Label)sender).Text );
            config.unit = 15;  //每移动一个单位(15像素),年份相应地加减
            config.unit1 = config.unit * 20;//1-20单位之间,1个1个地加减
            config.unit2 = config.unit * 30;//20-30单位之间,10个10个地加减
            config.unit3 = config.unit * 40;//30-40之间,每次加减20个;40以后,每次50个

        }

        
        /// <summary>年份移动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label_year_MouseMove(object sender, MouseEventArgs e)
        {
            if (config.yearBeginMove == true)
            {

                //Debug.WriteLine("---------");

                int y = MousePosition.Y;

                int direction = y - config.lastY;
                int dist = y - config.lastFixedY;
                //Debug.WriteLine("dist:" + y + "-" + config.lastFixedY + "=" + dist);
                //Debug.WriteLine("direction:" + y + "-" + config.lastY + "=" + direction);
                if (direction >= 2)
                {
                    config.lastY = y;  //把当前y记为上一步的y坐标,用来确定有无改变方向

                    if (this.Cursor != Cursors.PanSouth)
                    {
                        this.Cursor = Cursors.NoMoveVert;;
                        this.Cursor = Cursors.PanSouth;//改变方向为向下
                        //Debug.WriteLine("  S\n\n\n");
                        config.lastFixedY = y;  //把当前y记为上一个固定的y坐标,用来计算距离
                        
                        config.nextLevel = config.unit;
                    }

                    
                    if (dist>config.unit && dist <= config.unit1)
                    {
                        if (dist >= config.nextLevel)
                        {
                            config.originalYear += 1;
                            config.nextLevel += config.unit;
                        }
                    }
                    else if (dist > config.unit1 && dist <= config.unit2)
                    {
                        if (dist >= config.nextLevel)
                        {
                            config.originalYear += 10;
                            config.nextLevel += config.unit;
                        }
                    }
                    else if (dist > config.unit2 && dist <= config.unit3)
                    {
                        if (dist >= config.nextLevel)
                        {
                            config.originalYear += 20;
                            config.nextLevel += config.unit;
                        }
                    }
                    else if (dist > config.unit3)
                    {
                        if (dist >= config.nextLevel)
                        {
                            config.originalYear += 50;
                            config.nextLevel += config.unit;
                        }
                    }

                    //Debug.WriteLine("***changing:" + config.originalYear);
                    
                    if (((Label)sender).Equals(label_month))
                    {
                        ((Label)sender).Text = convertToMonth(config.originalYear);
                        return;
                    }
                    ((Label)sender).Text = config.originalYear.ToString();

                }
                else if (direction <= -2)
                {
                    config.lastY = y;

                    if (this.Cursor != Cursors.PanNorth) //改变方向为向上
                    {
                        this.Cursor = Cursors.NoMoveVert;
                        this.Cursor = Cursors.PanNorth;
                        
                        //Debug.WriteLine("  N\n\n\n");
                        config.lastFixedY = y;
                        
                        config.nextLevel = config.unit;
                    }

                    dist = 0 - dist;
                    if (dist > config.unit && dist <= config.unit1)
                    {
                        if (dist >= config.nextLevel)
                        {
                            config.originalYear -= 1;
                            config.nextLevel += config.unit;
                        }
                    }
                    else if (dist > config.unit1 && dist <= config.unit2)
                    {
                        if (dist >= config.nextLevel)
                        {
                            config.originalYear -= 10;
                            config.nextLevel += config.unit;
                        }
                    }
                    else if (dist > config.unit2 && dist <= config.unit3)
                    {
                        if (dist >= config.nextLevel)
                        {
                            config.originalYear -= 20;
                            config.nextLevel += config.unit;
                        }
                    }
                    else if (dist > config.unit3)
                    {
                        if (dist >= config.nextLevel)
                        {
                            config.originalYear -= 50;
                            config.nextLevel += config.unit;
                        }
                    }

                    //Debug.WriteLine("***changing:" + config.originalYear);

                    if (((Label)sender).Equals(label_month))
                    {
                        ((Label)sender).Text =convertToMonth(config.originalYear);
                        return;
                    }

                    ((Label)sender).Text = config.originalYear.ToString();

                }
            }
        }

        
        /// <summary>把一个值变成1-12之间的某个月
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public String convertToMonth(int value) {
            value = value % 12;
            if (value == 0) return "12";
            else if (value > 0) return value.ToString();
            else return (12 + value).ToString();
        }

        
        /// <summary>年份取消拖动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label_year_MouseUp(object sender, MouseEventArgs e)
        {
            config.yearBeginMove = false;
            this.Cursor = Cursors.Arrow;
            resetCalendar();
        }

        
        /// <summary>年份 鼠标进入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label_year_MouseEnter(object sender, EventArgs e)
        {
            if ((this.Cursor != Cursors.PanSouth) && (this.Cursor != Cursors.PanNorth)) this.Cursor = Cursors.NoMoveVert;
        }


        /// <summary>年份 鼠标离开
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label_year_MouseLeave(object sender, EventArgs e)
        {
            if (this.Cursor == Cursors.NoMoveVert) this.Cursor = Cursors.Arrow;
        }
        
        #endregion
        
        
        /// <summary>定时器控件,用来更新当前时间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e){
            label_nowtime.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");

            //时间每到新一天的0点,就更新今天的日期。
            if (DateTime.Now.Hour == 0 && DateTime.Now.Minute == 0 && DateTime.Now.Second == 0)
            {
                jumpToToday();
                //Debug.WriteLine("  test timer");
            }
        }


        /// <summary>更改年月之后,根据更改后的年月,来更新日历上的日期。
        /// 返回此月的第一天是星期几。
        /// </summary>
        /// <returns>返回此月的第一天是星期几</returns>
        public int resetCalendar() {
            int year = int.Parse(label_year.Text);
            int month = int.Parse(label_month.Text);

            //判断要设置的年月 是不是现在时间的年份月份。如果是,则在今天的日期上画框
            if (year == DateTime.Now.Year && month == DateTime.Now.Month) {
                ((Label)panel_calendar.Controls[config.todayIndex]).BorderStyle = BorderStyle.Fixed3D;
                config.isPaintedToday = true;
            }else if(config.isPaintedToday){ //如果不是,则判断今天所在的格子有没有标记,如果有则把今天的标记去掉
                ((Label)panel_calendar.Controls[config.todayIndex]).BorderStyle = BorderStyle.None;
                config.isPaintedToday = false;
            }

            //判断要设置的年月,是不是选中日期所在的年月。如果是,则在选中日期上做标记
            if (year == config.nowSelectedDay.Year && month == config.nowSelectedDay.Month)
            {
                //将上一个选中的日期的颜色改成蓝色
                ((Label)panel_calendar.Controls[config.nowSelectedDayIndex]).ForeColor =
                    Color.DeepSkyBlue;
            }
            else
            { //如果不是,则将上一个选中的日期的颜色改回默认白色
                ((Label)panel_calendar.Controls[config.nowSelectedDayIndex]).ForeColor =
                    SystemColors.ButtonHighlight;
            }

            CalendarHelper calendarHelper = new CalendarHelper();
            int dayNum = calendarHelper.howManyDays(year, month);
            int dayF2L = calendarHelper.whatDay(year, month);//第一天到最后一天
            int dayFirst = dayF2L;//此月第一天是星期几

            //Debug.WriteLine("  dayNum: " + dayNum);
            //Debug.WriteLine("  dayF2L: " + dayF2L);

            //把日期第一天以前的数据清空
            for (int i = 1; i < dayF2L; i++) {
                ((Label)panel_calendar.Controls[i-1]).Text = "";
            }

            //往日历面板上填日期
            for (int i = 1; i <= dayNum; i++)
            {
                ((Label)panel_calendar.Controls[dayF2L - 1]).Text = i.ToString();
                dayF2L++;
            }

            //把日期最后一天之后的数据清空.
            //panel_calendar.Controls.Count 等于 42。代表面板里有42个控件
            for (int i = dayF2L-1; i < 42; i++)
            {
                ((Label)panel_calendar.Controls[i]).Text = "";
                //calendarList[i].Text = "te";
            }

            return dayFirst;
        }

        /// <summary>把日期设置为当天日期
        /// </summary>
        public void jumpToToday() {

            int year = DateTime.Now.Year;
            int month = DateTime.Now.Month;
            config.todayDayInMonth = DateTime.Now.Day;
            label_year.Text = year.ToString();
            label_month.Text = month.ToString();

            CalendarHelper calendarHelper = new CalendarHelper();
            int dayFirst = calendarHelper.whatDay(year, month);
            config.todayIndex = (dayFirst + config.todayDayInMonth) - 1 - 1;

            if (config.nowSelectedDayIndex >= 0 && config.nowSelectedDayIndex <= 41)
            {
                //将上一个选中的日期的颜色改回默认白色,代表它不再被选中
                ((Label)panel_calendar.Controls[config.nowSelectedDayIndex]).ForeColor =
                    SystemColors.ButtonHighlight;
            }

            config.nowSelectedDay = new DateTime(year, month, config.todayDayInMonth);
            //将今天所在的下标,赋值给现在选中的日期的下标
            //默认选中今天
            config.nowSelectedDayIndex = config.todayIndex;
            resetDateInfoPanel(config.nowSelectedDay);//更新节气、节日等
            resetCalendar();
            
            //Debug.WriteLine("  dayfirst" + dayFirst);
            //Debug.WriteLine("  day" + DateTime.Now.Day);
            //Debug.WriteLine("  todayIndex" + todayIndex);
            
            events = selectDay(year, month, config.todayDayInMonth);
            resetEventPanel(events);
        }

        #region 现在时间 now按钮
        /// <summary>当前日期时间 按钮 点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label_nowtime_Click(object sender, EventArgs e)
        {
            jumpToToday();
            
        }


        /// <summary>鼠标进入 当前日期按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label_nowtime_MouseEnter(object sender, EventArgs e)
        {
            //((Label)sender).ForeColor = Color.DeepSkyBlue;
            label_nowtime.ForeColor = Color.DeepSkyBlue; ;
            label_nowtime_labal.ForeColor = Color.DeepSkyBlue; 
        }


        /// <summary>鼠标离开 当期日期按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label_nowtime_MouseLeave(object sender, EventArgs e)
        {
            //((Label)sender).ForeColor = Color.White;
            label_nowtime.ForeColor = Color.White;
            label_nowtime_labal.ForeColor = Color.White; 
        }
        #endregion


        /// <summary>日历面板中 子控件点击事件(日期点击)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label1_Click(object sender, EventArgs e)
        {
            if (config.isSelectedWholeYearEvent)
            {//如果全年事件处于选中状态,则把它设为不选中
                label_whole_year_event.ForeColor = Color.White;
                config.isSelectedWholeYearEvent = false;
            }

            if (((Label)sender).Text.Equals(""))//如果所选日期是空值,则不执行任何操作
            {
                Debug.Write("---click day: day is null");
            }
            else {//如果所选日期不是空值,说明它在日历上存在,则选中它

                int year = int.Parse(label_year.Text);
                int month = int.Parse(label_month.Text);
                int day = int.Parse(((Label)sender).Text);
                
                //将上一个选中的日期的颜色改回默认白色,代表它不再被选中
                ((Label)panel_calendar.Controls[config.nowSelectedDayIndex]).ForeColor =
                    SystemColors.ButtonHighlight;
                //将新选中的日期的字体颜色改为蓝色
                ((Label)sender).ForeColor = Color.DeepSkyBlue;
                //记录一下新选中的日期在日历中的下标
                config.nowSelectedDayIndex = panel_calendar.Controls.IndexOf((Control)sender);
                //记录一下新选中的日期
                config.nowSelectedDay = new DateTime(year, month, day);
                resetDateInfoPanel(config.nowSelectedDay);//更新节气、节日等
                events = selectDay(year, month, day);
                resetEventPanel(events);
            }
            

        }

        /// <summary>选中某一个日期,用来得到这个日期当天的备忘录事件
        /// </summary>
        /// <param name="year">年</param>
        /// <param name="month">月</param>
        /// <param name="day">日</param>
        public List<MyEvent> selectDay(int year, int month, int day)
        {
            Debug.WriteLine("-----select day:"+year+month+day);
            List<MyEvent> list;

            //#region 测试数据
            //list = new List<MyEvent>();
            //DateTime d1 = new DateTime(2018,12,10,20,04,00);
            //MyEvent m1 = new MyEvent("test1", "001", "n3", "2饭", d1, d1, d1, "note");
            //MyEvent m2 = new MyEvent("test2", "002", "n3", "2饭1楼", d1, d1, d1, "note");
            //list.Add(m1);
            //list.Add(m2);
            //#endregion

            DateTime datetime = new DateTime(year, month, day);
            MemoBLL.MemoBLL bll = new MemoBLL.MemoBLL();
            list = bll.getEvent(datetime);

            return list;
        }

        /// <summary>选择全年的备忘录事件
        /// </summary>
        /// <param name="year">年</param>
        public List<MyEvent> selectYear(int year) {
            Debug.WriteLine("-----select year:" + year);
            
            MemoBLL.MemoBLL bll = new MemoBLL.MemoBLL();
            List<MyEvent> list = bll.getEvent(year.ToString());
            return list;
        }

        /// <summary>重置备忘录事件面板
        /// </summary>
        /// <param name="list">备忘录事件列表</param>
        public void resetEventPanel(List<MyEvent> list){
            panel_event.Controls.Clear();//将原来显示的事件清空
            selectedEventsIndex.Clear();//清空已选中的多项事件的下标列表
            config.lastSelectedItemIndex = -1; //清空已选中的单项事件
            
            if (checkBoxAllSelect.CheckState == CheckState.Checked) {
                checkBoxAllSelect.CheckState = CheckState.Unchecked; //将全选框设置为取消选择
            }
            

            Debug.WriteLine("***重置事件面板: list数目: " + list.Count);

            MyEvent m;
            for (int i = 0; i < list.Count; i++) {
                m = ((MyEvent)list[i]);
                String startTime = m.getStartTime().ToString("yyyy/MM/dd HH:mm");
                String endTime = m.getEndTime().ToString("yyyy/MM/dd HH:mm");
                panel_event.Controls.Add(
                    createEventPanel(m.getEventName(),m.getOwner(), m.getPlace(),startTime, endTime));

            }
        }

        /// <summary>增加、修改、删除备忘录之后,刷新事件列表
        /// </summary>
        public void refreshEventPanel() {
            if (config.isSelectedWholeYearEvent)
            {
                events = selectYear(int.Parse(label_year.Text));
            }
            else
            {
                events = selectDay(config.nowSelectedDay.Year, config.nowSelectedDay.Month, config.nowSelectedDay.Day);
            }
            resetEventPanel(events);
        }

        #region 备忘录事件项,事件面板的创建
        
        /// <summary>创建一个放备忘录项的面板
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="owner"></param>
        /// <param name="place"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        public Panel createEventPanel(String eventName, String owner, String place, String startTime, String endTime)
        {
            Panel panel = new Panel();
            panel.BackgroundImage = global::MemorandumUI.Properties.Resources.transparent;

            #region 往面板中添加标签
            panel.Controls.Add(createEventNameLabel(eventName));
            panel.Controls.Add(createOwnerLabel(owner));
            panel.Controls.Add(createPlaceLabel(place));
            panel.Controls.Add(createStartTimeLabel(startTime));
            panel.Controls.Add(createEndTimeLabel(endTime));
            #endregion

            panel.Margin = new System.Windows.Forms.Padding(3, 3, 3, 6);
            
            panel.Size = new System.Drawing.Size(config.eventItemPanelWidth, config.eventItemPanelHeight);
            //Debug.WriteLine("++panel width:" + (int)(panel_event.Width));
            //Debug.WriteLine("++++ width:" + ((Label)panel4.Controls[0]).Text + " " + ((Label)panel4.Controls[0]).Width);
            //Debug.WriteLine("++++ width:" + ((Label)panel4.Controls[1]).Text + " " + ((Label)panel4.Controls[0]).Width);
            //Debug.WriteLine("++++ width:" + ((Label)panel4.Controls[2]).Text + " " + ((Label)panel4.Controls[0]).Width);
            //Debug.WriteLine("++++ width:" + ((Label)panel4.Controls[3]).Text + " " + ((Label)panel4.Controls[0]).Width);
            //Debug.WriteLine("++++ width:" + ((Label)panel4.Controls[4]).Text + " " + ((Label)panel4.Controls[0]).Width);
            panel.Click += new System.EventHandler(eventItem_Click);
            panel.DoubleClick += new EventHandler(eventItem_DoubleClick);
            return panel;
        }

        /// <summary>创建一个“备忘录名称”标签,(用来放入面板)
        /// </summary>
        /// <returns></returns>
        public Label createEventNameLabel(String eventName)
        {
            Label label = new Label();
            label.AutoSize = true;
            label.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            label.ForeColor = System.Drawing.Color.White;
            label.Location = new System.Drawing.Point(config.itemNameLabelX, config.itemNameLabelY);
            //label.Name = "label43";
            //label.Size = new System.Drawing.Size(config.itemNameLabelWidth, config.itemNameLabelHeight);
            //label.TabIndex = 0;
            label.Text = eventName;
            label.Click += new System.EventHandler(eventItem_Click);
            label.DoubleClick += new EventHandler(eventItem_DoubleClick);
            return label;
        }

        /// <summary>创建一个“备忘录所有者”标签,(用来放入面板)
        /// </summary>
        /// <returns></returns>
        public Label createOwnerLabel(String owner)
        {
            Label label = new Label();
            label.AutoSize = true;
            label.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            label.ForeColor = System.Drawing.Color.White;
            label.Location = new System.Drawing.Point(config.itemOwnerLabelX, config.itemOwnerLabelY);
            //label.Name = "label44";
            //label.Size = new System.Drawing.Size((int)(config.eventItemPanelWidth * 0.168), (int)(config.eventItemPanelHeight * 0.15));
            //label.TabIndex = 1;
            label.Text = "-- "+owner;
            label.Click += new System.EventHandler(eventItem_Click);
            label.DoubleClick += new EventHandler(eventItem_DoubleClick);
            return label;
        }

        /// <summary>创建一个“备忘录地点”标签,(用来放入面板)
        /// </summary>
        /// <returns></returns>
        public Label createPlaceLabel(String place)
        {
            Label label = new Label();
            label.AutoSize = true;
            label.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            label.ForeColor = System.Drawing.Color.White;
            label.Location = new System.Drawing.Point(config.itemPlaceLabelX, config.itemPlaceLabelY);
            //label.Name = "label45";
            //label.Size = new System.Drawing.Size(52, 15);
            //label.TabIndex = 2;
            label.Text = place;
            label.Click += new System.EventHandler(eventItem_Click);
            label.DoubleClick += new EventHandler(eventItem_DoubleClick);
            return label;
        }

        /// <summary>创建一个“备忘录开始时间”标签,(用来放入面板)
        /// </summary>
        /// <returns></returns>
        public Label createStartTimeLabel(String startTime)
        {
            Label label = new Label();
            label.AutoSize = true;
            label.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            label.ForeColor = System.Drawing.Color.White;
            label.Location = new System.Drawing.Point(config.itemStartTimeLabelX, config.itemStartTimeLabelY);
            //label.Name = "label46";
            //label.Size = new System.Drawing.Size(135, 15);
            //label.TabIndex = 3;
            label.Text = startTime;
            label.Click += new System.EventHandler(eventItem_Click);
            label.DoubleClick += new EventHandler(eventItem_DoubleClick);
            return label;
        }

        /// <summary>创建一个“备忘录结束时间”标签,(用来放入面板)
        /// </summary>
        /// <returns></returns>
        public Label createEndTimeLabel(String endTime)
        {
            Label label = new Label();
            label.AutoSize = true;
            label.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            label.ForeColor = System.Drawing.Color.White;
            label.Location = new System.Drawing.Point(config.itemEndTimeLabelX, config.itemEndTimeLabelY);
            //label.Name = "label47";
            //label.Size = new System.Drawing.Size(151, 15);
            //label.TabIndex = 4;
            label.Text = "-- "+endTime;
            label.Click += new System.EventHandler(eventItem_Click);
            label.DoubleClick += new EventHandler(eventItem_DoubleClick);
            return label;
        }

        
        /// <summary>备忘录事件的单击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void eventItem_Click(object sender, EventArgs e) {
            int nowSelectedItemIndex;//现在选中的事件项在事件面板中的索引是多少。
            if (sender.GetType() == typeof(Label))
            { //如果是点击了标签,则找到它的父控件,得到其父控件在事件面板中的索引。

                nowSelectedItemIndex = panel_event.Controls.IndexOf(((Label)sender).Parent);
            }
            else
            { //如果是点击了事件项面板,则找到其在事件面板中的索引。
                nowSelectedItemIndex = panel_event.Controls.IndexOf((Control)sender);
            }

            if (config.isMultiSelectOn)
            { //是否处于多选状态,如果是的话
                for (int i = 0; i < selectedEventsIndex.Count; i++) {
                    if (selectedEventsIndex[i] == nowSelectedItemIndex) { 
                        //如果该事件已经已经被选择,那第二次点击时要取消选择它
                        ((Panel)panel_event.Controls[nowSelectedItemIndex]).BorderStyle = BorderStyle.None;
                        selectedEventsIndex.RemoveAt(i);
                        return;

                    }
                }
                //如果该事件尚未被选择,则选中它,并把它加入到选中列表中.
                ((Panel)panel_event.Controls[nowSelectedItemIndex]).BorderStyle = BorderStyle.FixedSingle;
                selectedEventsIndex.Add(nowSelectedItemIndex);
            }
            else { //如果处于单选状态

                //Debug.WriteLine("-- -- --last selected " + config.lastSelectedItemIndex);
                //Debug.WriteLine("-- --now selected " + nowSelectedItemIndex);

                if (config.lastSelectedItemIndex != -1)
                {//如果存在上一个被选中的事件,

                    if (nowSelectedItemIndex == config.lastSelectedItemIndex)
                    {
                        //如果第二次点击的事件等于上一次点击的事件,则取消选择它,。
                        ((Panel)panel_event.Controls[config.lastSelectedItemIndex]).BorderStyle = BorderStyle.None;
                        config.lastSelectedItemIndex = -1;//然后将lastSelectedItemIndex设为-1,代表当前无选中,
                        return;//然后就可以退出此方法了
                    }

                    如果第二次点击的事件不等于上一次点击的事件,那么把上一个设为不选中。
                    ((Panel)panel_event.Controls[config.lastSelectedItemIndex]).BorderStyle = BorderStyle.None;


                }
                //把这一次点击的事件设为选中
                ((Panel)panel_event.Controls[nowSelectedItemIndex]).BorderStyle = BorderStyle.FixedSingle;
                config.lastSelectedItemIndex = nowSelectedItemIndex;
            }

            

            
            
        }

        /// <summary>备忘录事件的双击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void eventItem_DoubleClick(object sender, EventArgs e)
        {
            int nowSelectedItemIndex;//现在选中的事件项在事件面板中的索引是多少。
            if (sender.GetType() == typeof(Label))
            { //如果是点击了标签,则找到它的父控件,得到其父控件在事件面板中的索引。

                nowSelectedItemIndex = panel_event.Controls.IndexOf(((Label)sender).Parent);
            }
            else
            { //如果是点击了事件项面板,则找到其在事件面板中的索引。
                nowSelectedItemIndex = panel_event.Controls.IndexOf((Control)sender);
            }

            FormDetail form = new FormDetail(this.Location, ((MyEvent)events[nowSelectedItemIndex]));

            form.ShowDialog();
        }

        /// <summary>将已选中的事件设置为不选中, 主要用于多条事件的释放
        /// </summary>
        public void setItemsUnselected() {
            for (int i = 0; i < selectedEventsIndex.Count; i++) {
                ((Panel)panel_event.Controls[selectedEventsIndex[i]]).BorderStyle
                    = BorderStyle.None;
            }
        }

        #endregion


        /// <summary>解决窗体闪烁,,但是会发生其他异常,比如置于底层之后控件消失
        /// </summary>
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }

        /// <summary>窗体最小化之后无法正常恢复,刷新一下视图让它恢复显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormMain_SizeChanged(object sender, EventArgs e)
        {
            //Debug.WriteLine("...窗体改变  ");
            if (this.WindowState == FormWindowState.Normal) {
                for (int i = 0; i < this.Controls.Count; i++) {
                    this.Controls[i].Refresh();
                    //Debug.WriteLine("...窗体刷新  "+i);
                }
                this.Refresh();
                //Debug.WriteLine("...窗体刷新  ");
            }
        }

        
        /// <summary>修改用户名 点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void labelOwner_Click(object sender, EventArgs e)
        {
            FormResetOwner form = new FormResetOwner(this.Location);
            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
                labelOwner.Text = form.getOwnerName();
            }
        }

        /// <summary>多选模式 点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkBoxMultiSelect_CheckStateChanged(object sender, EventArgs e)
        {
            if (checkBoxMultiSelect.CheckState == CheckState.Checked)
            {
                config.isMultiSelectOn = true;
                if (config.lastSelectedItemIndex != -1) {
                    //将上一次选中的事件(如果有的话)先加入多选事件下标的列表
                    selectedEventsIndex.Add(config.lastSelectedItemIndex);
                }
                
                //Debug.WriteLine("///多选开启");
            }
            else {
                config.isMultiSelectOn = false;
                setItemsUnselected();
                selectedEventsIndex.Clear();
                //Debug.WriteLine("///多选关闭");
            }
        }

        /// <summary>全选框 状态发生改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkBoxAllSelect_CheckStateChanged(object sender, EventArgs e)
        {
            
            if ( checkBoxAllSelect.CheckState == CheckState.Checked)
            {
                config.isAllEventSelected = true;
                checkBoxMultiSelect.CheckState = CheckState.Checked;
                //Debug.WriteLine("///全选开启");
                selectedEventsIndex.Clear();//先清空多选的事件列表,避免待会加入重复的下标
                setAllEventsStyle(BorderStyle.FixedSingle);
            }
            else
            {
                config.isAllEventSelected = false;
                //Debug.WriteLine("///全选关闭");
                setAllEventsStyle(BorderStyle.None);
                selectedEventsIndex.Clear();
            }
        }

        /// <summary>更改备忘录列表中的所有事件的样式
        /// </summary>
        /// <param name="style"></param>
        public void setAllEventsStyle(BorderStyle style) {
            for (int i = 0; i < panel_event.Controls.Count; i++)
            {
                selectedEventsIndex.Add(i);
                ((Panel)panel_event.Controls[i]).BorderStyle = style;
            }
        }

        /// <summary>修改按钮 点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_change_Click(object sender, EventArgs e)
        {
            MyEvent myEvent;
            if (config.isMultiSelectOn) {
                //如果开启了多选,且只选中了一个事件,那么可以修改修改。
                if (selectedEventsIndex.Count == 1)
                {
                    myEvent = (MyEvent)events[selectedEventsIndex[0]];
                }
                else return; //如果选了多个,则直接返回。
            }else{
                //只允许修改单个事件,,且只有当某个事件被选中的时候才可以更改。
                if (config.lastSelectedItemIndex != -1)
                {
                    myEvent = events[config.lastSelectedItemIndex];
                }
                else return;//如果一个都没选,则直接返回。
            }
            FormAdd form = new FormAdd(this.Location, myEvent, labelOwner.Text);
            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                refreshEventPanel();
            }
        }

        /// <summary>删除按钮 点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_del_Click(object sender, EventArgs e)
        {
            List<MyEvent> list = new List<MyEvent>();
            if (config.isMultiSelectOn)//选了多条备忘录 要拿来删除
            {
                for (int i = 0; i < selectedEventsIndex.Count; i++) {
                    list.Add( ((MyEvent)events[selectedEventsIndex[i]]) );
                }
            }
            else if (config.lastSelectedItemIndex == -1)
            { //没选任何备忘录
                return;
            }
            else { //选了一条备忘录要拿来删除
                list.Add((MyEvent)events[config.lastSelectedItemIndex]);
            }
            MemoBLL.MemoBLL bll = new MemoBLL.MemoBLL();
            bll.deletEvent(list);
            refreshEventPanel();
        }

        /// <summary>重置与日期相关的节日、农历等信息。
        /// </summary>
        public void resetDateInfoPanel(DateTime datetime)
        {
            ChineseCalendar cc = new ChineseCalendar(datetime);
            detail_label_so_year.Text = datetime.ToString("yyyy-MM-dd");

            int yearIndex = cc.ChineseDateString.IndexOf('年');
            String lunarYear = cc.ChineseDateString.Substring(0, yearIndex + 1);
            String lunarMonthDay = cc.ChineseDateString.Substring(yearIndex + 1);
            detail_label_lu_year.Text = lunarYear;
            detail_label_lu_monthDay.Text = lunarMonthDay;

            detail_label_xinzuo.Text = cc.Constellation;
            detail_label_holiday.Text = (cc.DateHoliday + " " + cc.WeekDayHoliday).Trim();
            detail_label_jieqi.Text = (cc.ChineseTwentyFourDay + " " + cc.ChineseCalendarHoliday).Trim() ;
            detail_label_animal.Text = cc.AnimalString+"年";
        }
    }

    /// <summary>配置信息,用于做一些状态的标记,如是否选择全年事件
    /// </summary>
    public class Config
    {
        /// <summary>判断是否已选择全年备忘录时间
        /// </summary>
        public bool isSelectedWholeYearEvent = false;

        #region 年份、月份拖动 要用到的属性
        public bool yearBeginMove = false; //年份拖动
        public int yearOriginalPointY;
        public int lastY;
        public int lastFixedY;
        public int originalYear;
        public int nextLevel;
        public int unit;
        public int unit1;
        public int unit2;
        public int unit3;
        #endregion


        /// <summary>用于标记日历上 今天所在的位置 有没有画框
        /// </summary>
        public bool isPaintedToday=false ;
        /// <summary>今天应该存放在日历的哪一个格子(下标)
        /// </summary>
        public int todayIndex;
        /// <summary>今天是几号
        /// </summary>
        public int todayDayInMonth;


        /// <summary>现在选中的日期放在日历的哪一个格子(下标)
        /// </summary>
        public int nowSelectedDayIndex;
        /// <summary>现在选中的日期的年月日是什么
        /// </summary>
        public DateTime nowSelectedDay;

        #region 与备忘录列表有关的参数
        public int eventItemPanelWidth; //每一项事件的宽度
        public int eventItemPanelHeight; //每一项事件的高度

        public int itemNameLabelX;
        public int itemNameLabelY;
        public int itemNameLabelWidth;
        public int itemNameLabelHeight;

        public int itemOwnerLabelX;
        public int itemOwnerLabelY;

        public int itemPlaceLabelX;
        public int itemPlaceLabelY;

        public int itemStartTimeLabelX;
        public int itemStartTimeLabelY;

        public int itemEndTimeLabelX;
        public int itemEndTimeLabelY;

        /// <summary>上一个被选中的事件的下标,如果此值为-1,代表没有事件被选中
        /// </summary>
        public int lastSelectedItemIndex = -1;

        /// <summary>列表中的事件是否全部被选中
        /// </summary>
        public bool isAllEventSelected=false;

        /// <summary>是否开启多选模式
        /// </summary>
        public bool isMultiSelectOn=false;

        /// <summary>根据整个事件面板的长和宽,初始化备忘录事件项的长和宽,以及其中的标签的大小和位置
        /// </summary>
        /// <param name="width">备忘录事件面板的宽度</param>
        /// <param name="height">备忘录事件面板的长度</param>
        public void initialItemPanel(int width, int height) {
            eventItemPanelWidth = (int)(width * 0.85);
            eventItemPanelHeight = (int)(height * 0.224);

            itemNameLabelX =  (int)(eventItemPanelWidth * 0.026);
            itemNameLabelY = (int)(eventItemPanelHeight * 0.028);
            //itemNameLabelWidth = (int)(eventItemPanelWidth*0.64);
            //itemNameLabelHeight = (int)(eventItemPanelHeight * 0.23);

            itemOwnerLabelX = (int)(eventItemPanelWidth * 0.728);
            itemOwnerLabelY = (int)(eventItemPanelHeight * 0.084);

            itemPlaceLabelX = (int)(eventItemPanelWidth * 0.142);
            itemPlaceLabelY = (int)(eventItemPanelHeight * 0.336);

            itemStartTimeLabelX = (int)(eventItemPanelWidth * 0.228);
            itemStartTimeLabelY = (int)(eventItemPanelHeight * 0.579);

            itemEndTimeLabelX = itemStartTimeLabelX;
            itemEndTimeLabelY = (int)(eventItemPanelHeight * 0.785);

        }
        #endregion

        //public bool beginMove = false;//拖动窗体,初始化鼠标位置
        //public int currentXPosition;//初始化鼠标位置
        //public int currentYPosition;//初始化鼠标位置


    }
}

FormAdd.cs

using MemoModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MemoBLL;

namespace Memorandum
{
    public partial class FormAdd : Form
    {
        String ownerName;
        String newOwnerName;
        string eventId;
        //List<MyEvent> events;

        #region 控制无边框窗体的移动
        //using System.Runtime.InteropServices;
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        #endregion

        /// <summary>增加备忘录
        /// </summary>
        /// <param name="p"></param>
        /// <param name="ownerName"></param>
        /// <param name="datetime"></param>
        public FormAdd(Point p,String ownerName,DateTime datetime)
        {
            InitializeComponent();
            this.ownerName = ownerName;
            this.SetDesktopLocation(p.X+80, p.Y+100);
            dateTimePicker1.Value = datetime;
            dateTimePicker2.Value = datetime;
            dateTimePicker3.Value = datetime;
            //生成新的eventId
            eventId = DateTime.Now.ToString("yyyyMMddHHmmss"); //生成eventId格式是yyyyMMddHHmmss
            //Debug.WriteLine("副 添加 坐标:" + this.Location.X + " " + this.Location.Y);
        }

        /// <summary>修改备忘录
        /// </summary>
        /// <param name="myEvent">要修改的事件</param>
        /// <param name="newOwnerName">新的创建者</param>
        /// <param name="p">主界面的坐标</param>
        public FormAdd(Point p ,MyEvent myEvent, String newOwnerName) {
            InitializeComponent();
            this.SetDesktopLocation(p.X + 80, p.Y + 100);
            ownerName = myEvent.getOwner();//旧的owner,用来找到旧的备忘录,并把它删掉
            this.newOwnerName = newOwnerName; //新的owner,用来创建新事件
            label_title.Text = "修改备忘录";

            //要修改备忘录的时候,先不要修改它的eventId,id用来找到旧的那条备忘录,把它删掉
            eventId = myEvent.getEventId();
            textBox2.Text = myEvent.getEventName();
            textBox1.Text = myEvent.getPlace();
            dateTimePicker1.Value = myEvent.getStartTime();
            dateTimePicker2.Value = myEvent.getEndTime(); 
            dateTimePicker3.Value = myEvent.getRemindTime();
            textBox3.Text = myEvent.getEventNote(); 
        }

        //最小化 点击
        private void button1_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }


        //关闭 点击
        private void button2_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //拖动 按下
        private void panel3_MouseDown(object sender, MouseEventArgs e)
        {

            //常量
            int WM_SYSCOMMAND = 0x0112;
 
            //窗体移动
            int SC_MOVE = 0xF010;
            int HTCAPTION = 0x0002;
 
            ReleaseCapture();
            SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);

        }


        //取消按钮
        private void button3_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //确定按钮
        private void btn_add_Click(object sender, EventArgs e)
        {
            String eventName = textBox2.Text;
            String owner = ownerName;
            String place = textBox1.Text;
            DateTime startTime = dateTimePicker1.Value;
            DateTime endTime = dateTimePicker2.Value;
            DateTime remindTime = dateTimePicker3.Value;
            String eventNote = textBox3.Text;

            MyEvent myEvent = new MyEvent(eventName , eventId, owner, place, 
                startTime, endTime, remindTime, eventNote);
            
            MemoBLL.MemoBLL bll = new MemoBLL.MemoBLL();

            //Debug.WriteLine("---添加按钮-----点击 " + myEvent.getEventName() + " 框名: " + label_title.Text);
            if (label_title.Text.Equals("添加备忘录"))
            {
                List<MyEvent> list = new List<MyEvent>();
                list.Add(myEvent);
                //Debug.WriteLine("---添加了一条备忘录:" + myEvent.getEventName());
                bll.addEvent(list);
            }
            else if (label_title.Text.Equals("修改备忘录"))
            {
                //Debug.WriteLine("---note: "+myEvent.getEventNote());
                bll.changeEvent(myEvent, newOwnerName);
            }

            this.DialogResult = System.Windows.Forms.DialogResult.OK; //把窗口返回结果设置为OK
        }

    }

}

FormDetail.cs

using MemoModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MemoBLL;

namespace Memorandum
{
    public partial class FormDetail : Form
    {
        
        //List<MyEvent> events;

        #region 控制无边框窗体的移动
        //using System.Runtime.InteropServices;
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        #endregion

        /// <summary>构造一个备忘录详细信息的窗体。
        /// </summary>
        /// <param name="p">主窗体的坐标</param>
        /// <param name="myEvent">要详细展示的备忘录事件</param>
        public FormDetail(Point p, MyEvent myEvent)
        {
            InitializeComponent();

            textBoxName.Text = myEvent.getEventName();
            textBoxEventId.Text = myEvent.getEventId();
            textBoxOwner.Text = myEvent.getOwner();
            textBoxStartTime.Text = myEvent.getStartTime().ToString("yyyy/MM/dd HH:mm");
            textBoxRemindTime.Text = myEvent.getRemindTime().ToString("yyyy/MM/dd HH:mm");
            textBoxEndTime.Text = myEvent.getEndTime().ToString("yyyy/MM/dd HH:mm");
            textBoxNote.Text = myEvent.getEventNote();
            textBoxPlace.Text = myEvent.getPlace();

            this.SetDesktopLocation(p.X+80, p.Y+100);
            //Debug.WriteLine("副 添加 坐标:" + this.Location.X + " " + this.Location.Y);
        }

        

        

        //最小化 点击
        private void button1_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }


        //关闭 点击
        private void button2_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        //拖动 按下
        private void panel3_MouseDown(object sender, MouseEventArgs e)
        {

            //常量
            int WM_SYSCOMMAND = 0x0112;
 
            //窗体移动
            int SC_MOVE = 0xF010;
            int HTCAPTION = 0x0002;
 
            ReleaseCapture();
            SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);

        }

    }

}

FormResetOwner.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tool;

namespace MemorandumUI
{
    public partial class FormResetOwner : Form
    {
        private String ownerName;
        public FormResetOwner(Point p)
        {
            InitializeComponent();
            this.SetDesktopLocation(p.X + 80, p.Y + 100);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FileHelper fileHelper = new FileHelper();
            ownerName = textBox1.Text;
            if (ownerName.Trim() == String.Empty) {
                MessageBox.Show("用户名不能为空");
                return;
            }
            fileHelper.writeOwner(ownerName);
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }

        public String getOwnerName() {
            return ownerName;
        }
    }
}

Resources

transparent这张图是用ps做的半透明的图,在这里看不出来,png格式的。两个button也是透明背景的。

 

5.4 MemoModel

MemoModel.cs

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MemoModel
{
    public class MemoModel
    {
    }


    public class MyEvent
    {
        [JsonProperty]
        private string eventName;  
        //要在每个属性前面声明它要用到json,否则在Deserialize的时候会生成空的MyEvent
        [JsonProperty]
        private string eventId;
        [JsonProperty]
        private string owner;
        [JsonProperty]
        private string place;
        [JsonProperty]
        private DateTime startTime;
        [JsonProperty]
        private DateTime endTime;
        [JsonProperty]
        private DateTime remindTime;
        [JsonProperty]
        private string eventNote;

        public MyEvent(string eventName, String eventId, String owner, string place, DateTime startTime, DateTime endTime, DateTime remindTime, string eventNote)
        {
            this.eventName = eventName;
            this.eventId = eventId;
            this.owner = owner;
            this.place = place;
            this.startTime = startTime;
            this.endTime = endTime;
            this.remindTime = remindTime;
            this.eventNote = eventNote;
        }

        public void setEventId(String eventId)
        {
            this.eventId = eventId;
        }
        public String getEventId()
        {
            return eventId;
        }

        public void setOwner(String owner)
        {
            this.owner = owner;
        }
        public String getOwner()
        {
            return owner;
        }

        public string getEventName()
        {
            return eventName;
        }
        public void setEventName(string eventName)
        {
            this.eventName = eventName;
        }

        public string getPlace()
        {
            return place;
        }
        public void setPlace(string place)
        {
            this.place = place;
        }

        public DateTime getStartTime()
        {
            return startTime;
        }
        public void setStartTime(DateTime startTime)
        {
            this.startTime = startTime;
        }

        public DateTime getEndTime()
        {
            return endTime;
        }
        public void setEndTime(DateTime endTime)
        {
            this.endTime = endTime;
        }

        public DateTime getRemindTime()
        {
            return remindTime;
        }
        public void setRemindTime(DateTime remindTime)
        {
            this.remindTime = remindTime;
        }

        public string getEventNote()
        {
            return eventNote;
        }
        public void setEventNote(string eventNote)
        {
            this.eventNote = eventNote;
        }
    }
}

 

 

5.5 Tool

(其中有一个功能是在csdn上找的,觉得挺不错,就借用了。原文:https://blog.csdn.net/kinglearnjava/article/details/43733377)

tool.cs

using MemoModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace Tool
{
    /// <summary>此类用来存取文件。
    /// </summary>
    public class FileHelper
    {
        /// <summary>用来保存本地数据的文档的路径,暂时只用来保存创建者
        /// </summary>
        string dataFilePathName;

        public FileHelper(){
            DirectoryInfo rootDir = Directory.GetParent(Environment.CurrentDirectory);
            String rootPath= rootDir.Parent.Parent.FullName;
            dataFilePathName = rootPath + "\\data\\owner.txt";
            //Debug.WriteLine("-=+++测试路径:" + dataFilePathName);
        }

        /// <summary>将当前选中年份的所有备忘录事件,以json格式存至本地,存储格式为txt文件
        /// </summary>
        /// <param name="lists">要保存的备忘录数据列表</param>
        /// <param name="path">保存文件路径</param>
        /// <param name="selectedItemIndex">被选中的事件的下标</param>
        public void save(List<MyEvent> lists, List<int> selectedItemIndex, String path)
        {

            FileStream fs = new FileStream(path, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            String str;

            for (int i = 0; i < selectedItemIndex.Count; i++)
            {
                Debug.WriteLine("------selectedItemIndex.Count " + selectedItemIndex.Count + " 第" + i + "是: " + selectedItemIndex[i]);
                Debug.WriteLine("save.list " + ((MyEvent)lists[selectedItemIndex[i]]).getEventName());

                str = JsonConvert.SerializeObject(((MyEvent)lists[selectedItemIndex[i]]));
                Debug.WriteLine("save: " + str);

                sw.WriteLine(str);//写至缓冲区
                sw.Flush();//清空缓冲区,将内容从缓冲区写到文件里去
                
            }
            sw.Close();//关闭输出流
            fs.Close();//关闭文件流

        }

        /// <summary>将txt文件中json格式的数据,读取出来成备忘录事件(MyEvent),返回所有备忘录列表
        /// </summary>
        /// <param name="filePathName">读取文件路径</param>
        /// <returns></returns>
        public List<MyEvent> read(String filePathName)
        {
            Debug.WriteLine("----read file path: "+filePathName);
            StreamReader sr = new StreamReader(filePathName, Encoding.Default);
            String line;

            MyEvent myEvent;
            List<MyEvent> list = new List<MyEvent>();

            try
            {
                while ((line = sr.ReadLine()) != null)
                {
                    myEvent = JsonConvert.DeserializeObject<MyEvent>(line);
                    //Console.WriteLine(line.ToString());
                    //Debug.WriteLine(line.ToString());

                    Debug.WriteLine("test:  " + myEvent.getEventId() + " " + myEvent.getEventName() + " " + myEvent.getStartTime().ToString() + " " + myEvent.getEventNote());
                    list.Add(myEvent);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("读取文件异常发生:" + e.Message);
            }

            sr.Close();//关闭文件输出流
            return list;
        }

        /// <summary>读取本地的 用户名
        /// </summary>
        /// <returns></returns>
        public String readOwner() {
            FileStream file = new FileStream(dataFilePathName, FileMode.OpenOrCreate);
            StreamReader sr = new StreamReader(file);
            String str = sr.ReadLine();
            if (str == null)
            {
                //Debug.WriteLine("--!!!!空文件");
                StreamWriter sw = new StreamWriter(file);
                str = "默认用户";
                sw.Write(str);
                sw.Flush();
                sw.Close();
            }

            //Debug.WriteLine("-- owner:  "+str);
            sr.Close();
            file.Close();
            return str;
        }

        /// <summary>将用户名写入本地
        /// </summary>
        public void writeOwner(String ownerName) {
            FileStream file = new FileStream(dataFilePathName, FileMode.Create);
            StreamWriter sw = new StreamWriter(file);
            sw.Write(ownerName);
            sw.Flush();
            sw.Close();
            file.Close();
            
        }
    }

    /// <summary>此类用来帮助生成日历信息
    /// </summary>
    public class CalendarHelper
    {


        /// <summary> 判断某个月第一天是星期几,转自CSDN
        /// </summary>
        /// <param name="currentYear"><seealso cref="哪一年"/></param>
        /// <param name="month"><seealso cref="哪个月"/></param>
        /// <para>sadasdafdsfsad</para>
        //作者:DAIBAOZHI  来源:CSDN 原文:https://blog.csdn.net/DAIBAOZHI/article/details/80738697 
        public int whatDay(int currentYear, int month)//判断从某年某月第一天是星期几
        {
            int num;
            int totalDays = 0;
            for (int i = 1900; i < currentYear; i++)
            {
                //if (IsLeapYear(i))
                if (DateTime.IsLeapYear(i))
                {
                    totalDays += 366;
                }
                else
                {
                    totalDays += 365;
                }

            }
            for (int j = 1; j < month; j++)
            {
                totalDays += howManyDays(currentYear, j);
            }

            num = totalDays % 7;
            return num + 1;
        }

        /// <summary> 判断某一年的某个月有多少天,转自CSDN
        /// </summary>
        /// <param name="year"><seealso cref="哪一年"/></param>
        /// <param name="month"><seealso cref="哪个月"/></param>
        /// <paramref name="year"/>
        //作者:DAIBAOZHI  来源:CSDN 原文:https://blog.csdn.net/DAIBAOZHI/article/details/80738697 
        public int howManyDays(int year, int month)//判断某年每个月的天数
        {
            int i = month;
            int monthDay;
            if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
            {
                monthDay = 31;
            }

            else if (i == 4 || i == 6 || i == 9 || i == 11)
            {
                monthDay = 30;
            }

            else if (i == 2 && DateTime.IsLeapYear(year) == true)
            {
                //IsLeapYear(year)
                monthDay = 29;
            }
            else
            {
                monthDay = 28;
            }
            return monthDay;
        }

        /<summary>判断是不是闰年,转自CSDN</summary>
        作者:DAIBAOZHI  来源:CSDN 原文:https://blog.csdn.net/DAIBAOZHI/article/details/80738697 
        //public bool IsLeapYear(int year)//判断某年是不是闰年
        //{
        //    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
        //    {
        //        //   Console.WriteLine("shi 闰年");
        //        return true;
        //    }
        //    else
        //    {
        //        //   Console.WriteLine("不是 闰年");
        //        return false;
        //    }
        //}

    }


    #region 根据日期生成节气、农历、星座、属相等信息。 转载自CSDN,作者:KingLearnJava,网址:https://blog.csdn.net/kinglearnjava/article/details/43733377

    #region 用法示例 Demo

    //DateTime dt = DateTime.Now;
    //ChineseCalendar cc = new ChineseCalendar(dt);
    //Console.WriteLine("阳历:" + cc.DateString);
    //Console.WriteLine("属相:" + cc.AnimalString);
    //Console.WriteLine("农历:" + cc.ChineseDateString);
    //Console.WriteLine("时辰:" + cc.ChineseHour);
    //Console.WriteLine("节气:" + cc.ChineseTwentyFourDay);
    //Console.WriteLine("节日:" + cc.DateHoliday);
    //Console.WriteLine("前一个节气:" + cc.ChineseTwentyFourPrevDay);
    //Console.WriteLine("后一个节气:" + cc.ChineseTwentyFourNextDay);
    //Console.WriteLine("干支:" + cc.GanZhiDateString);
    //Console.WriteLine("星期:" + cc.WeekDayStr);
    //Console.WriteLine("星宿:" + cc.ChineseConstellation);
    //Console.WriteLine("星座:" + cc.Constellation);
    #endregion

    #region ChineseCalendarException 中国日历异常处理
    /// <summary>中国日历异常处理
    /// </summary>
    public class ChineseCalendarException : System.Exception
    {
        public ChineseCalendarException(string msg)
            : base(msg)
        {
        }
    }
    #endregion

    /// <summary>中国农历类 版本V1.0 支持 1900.1.31日起至 2049.12.31日止的数据
    /// </summary>
    /// <remarks>
    /// 本程序使用数据来源于网上的万年历查询,并综合了一些其它数据
    /// </remarks>
    public class ChineseCalendar
    {
        /// <summary>内部结构
        /// </summary>
        #region 内部结构
        private struct SolarHolidayStruct
        {
            public int Month;
            public int Day;
            /// <summary>假期长度
            /// </summary>
            public int Recess; 
            public string HolidayName;
            public SolarHolidayStruct(int month, int day, int recess, string name)
            {
                Month = month;
                Day = day;
                Recess = recess;
                HolidayName = name;
            }
        }
        private struct LunarHolidayStruct
        {
            public int Month;
            public int Day;
            public int Recess;
            public string HolidayName;
            public LunarHolidayStruct(int month, int day, int recess, string name)
            {
                Month = month;
                Day = day;
                Recess = recess;
                HolidayName = name;
            }
        }
        private struct WeekHolidayStruct
        {
            public int Month;
            public int WeekAtMonth;
            public int WeekDay;
            public string HolidayName;
            public WeekHolidayStruct(int month, int weekAtMonth, int weekDay, string name)
            {
                Month = month;
                WeekAtMonth = weekAtMonth;
                WeekDay = weekDay;
                HolidayName = name;
            }
        }
        #endregion


        #region 内部变量
        private DateTime _date;
        private DateTime _datetime;
        private int _cYear;
        private int _cMonth;
        private int _cDay;
        private bool _cIsLeapMonth; //当月是否闰月
        private bool _cIsLeapYear; //当年是否有闰月
        #endregion

        #region 基础数据
        #region 基本常量
        private const int MinYear = 1900;
        private const int MaxYear = 2050;
        private static DateTime MinDay = new DateTime(1900, 1, 30);
        private static DateTime MaxDay = new DateTime(2049, 12, 31);
        private const int GanZhiStartYear = 1864; //干支计算起始年
        private static DateTime GanZhiStartDay = new DateTime(1899, 12, 22);//起始日
        private const string HZNum = "零一二三四五六七八九";
        private const int AnimalStartYear = 1900; //1900年为鼠年
        private static DateTime ChineseConstellationReferDay = new DateTime(2007, 9, 13);//28星宿参考值,本日为角
        #endregion

        #region 阴历数据
        /// <summary>来源于网上的农历数据
        /// </summary>
        /// <remarks>
        /// 数据结构如下,共使用17位数据
        /// 第17位:表示闰月天数,0表示29天   1表示30天
        /// 第16位-第5位(共12位)表示12个月,其中第16位表示第一月,如果该月为30天则为1,29天为0
        /// 第4位-第1位(共4位)表示闰月是哪个月,如果当年没有闰月,则置0
        ///</remarks>
        private static int[] LunarDateArray = new int[]{
                0x04BD8,0x04AE0,0x0A570,0x054D5,0x0D260,0x0D950,0x16554,0x056A0,0x09AD0,0x055D2,
                0x04AE0,0x0A5B6,0x0A4D0,0x0D250,0x1D255,0x0B540,0x0D6A0,0x0ADA2,0x095B0,0x14977,
                0x04970,0x0A4B0,0x0B4B5,0x06A50,0x06D40,0x1AB54,0x02B60,0x09570,0x052F2,0x04970,
                0x06566,0x0D4A0,0x0EA50,0x06E95,0x05AD0,0x02B60,0x186E3,0x092E0,0x1C8D7,0x0C950,
                0x0D4A0,0x1D8A6,0x0B550,0x056A0,0x1A5B4,0x025D0,0x092D0,0x0D2B2,0x0A950,0x0B557,
                0x06CA0,0x0B550,0x15355,0x04DA0,0x0A5B0,0x14573,0x052B0,0x0A9A8,0x0E950,0x06AA0,
                0x0AEA6,0x0AB50,0x04B60,0x0AAE4,0x0A570,0x05260,0x0F263,0x0D950,0x05B57,0x056A0,
                0x096D0,0x04DD5,0x04AD0,0x0A4D0,0x0D4D4,0x0D250,0x0D558,0x0B540,0x0B6A0,0x195A6,
                0x095B0,0x049B0,0x0A974,0x0A4B0,0x0B27A,0x06A50,0x06D40,0x0AF46,0x0AB60,0x09570,
                0x04AF5,0x04970,0x064B0,0x074A3,0x0EA50,0x06B58,0x055C0,0x0AB60,0x096D5,0x092E0,
                0x0C960,0x0D954,0x0D4A0,0x0DA50,0x07552,0x056A0,0x0ABB7,0x025D0,0x092D0,0x0CAB5,
                0x0A950,0x0B4A0,0x0BAA4,0x0AD50,0x055D9,0x04BA0,0x0A5B0,0x15176,0x052B0,0x0A930,
                0x07954,0x06AA0,0x0AD50,0x05B52,0x04B60,0x0A6E6,0x0A4E0,0x0D260,0x0EA65,0x0D530,
                0x05AA0,0x076A3,0x096D0,0x04BD7,0x04AD0,0x0A4D0,0x1D0B6,0x0D250,0x0D520,0x0DD45,
                0x0B5A0,0x056D0,0x055B2,0x049B0,0x0A577,0x0A4B0,0x0AA50,0x1B255,0x06D20,0x0ADA0,
                0x14B63        
                };
        #endregion

        #region 星座名称
        private static string[] _constellationName = 
                { 
                    "白羊座", "金牛座", "双子座", 
                    "巨蟹座", "狮子座", "处女座", 
                    "天秤座", "天蝎座", "射手座", 
                    "摩羯座", "水瓶座", "双鱼座"
                };
        #endregion

        #region 二十四节气
        private static string[] _lunarHolidayName = 
                    { 
                    "小寒", "大寒", "立春", "雨水", 
                    "惊蛰", "春分", "清明", "谷雨", 
                    "立夏", "小满", "芒种", "夏至", 
                    "小暑", "大暑", "立秋", "处暑", 
                    "白露", "秋分", "寒露", "霜降", 
                    "立冬", "小雪", "大雪", "冬至"
                    };
        #endregion

        #region 二十八星宿
        private static string[] _chineseConstellationName =
            {
                  //四        五      六         日        一      二      三  
                "角木蛟","亢金龙","女土蝠","房日兔","心月狐","尾火虎","箕水豹",
                "斗木獬","牛金牛","氐土貉","虚日鼠","危月燕","室火猪","壁水獝",
                "奎木狼","娄金狗","胃土彘","昴日鸡","毕月乌","觜火猴","参水猿",
                "井木犴","鬼金羊","柳土獐","星日马","张月鹿","翼火蛇","轸水蚓" 
            };
        #endregion

        #region 节气数据
        private static string[] SolarTerm = new string[] { "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };
        private static int[] sTermInfo = new int[] { 0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758 };
        #endregion

        #region 农历相关数据
        private static string ganStr = "甲乙丙丁戊己庚辛壬癸";
        private static string zhiStr = "子丑寅卯辰巳午未申酉戌亥";
        private static string animalStr = "鼠牛虎兔龙蛇马羊猴鸡狗猪";
        private static string nStr1 = "日一二三四五六七八九";
        private static string nStr2 = "初十廿卅";
        private static string[] _monthString =
                {
                    "出错","正月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","腊月"
                };
        #endregion

        #region 按公历计算的节日
        private static SolarHolidayStruct[] sHolidayInfo = new SolarHolidayStruct[]{
            new SolarHolidayStruct(1, 1, 1, "元旦"),
            new SolarHolidayStruct(1, 4, 0, "黑人日"),
            new SolarHolidayStruct(1, 25, 0, "国际麻风节"),
            new SolarHolidayStruct(2, 2, 0, "世界湿地日"),
            new SolarHolidayStruct(2, 7, 0, "国际声援南非日"),
            new SolarHolidayStruct(2, 10, 0, "国际气象节"),
            new SolarHolidayStruct(2, 14, 0, "情人节"),
            new SolarHolidayStruct(2, 21, 0, "反对殖民制度斗争日"),
            new SolarHolidayStruct(2, 24, 0, "第三世界青年日"),
            new SolarHolidayStruct(2, 28, 0, "世界居住条件调查日"),
            new SolarHolidayStruct(3, 1, 0, "国际海豹日"),
            new SolarHolidayStruct(3, 3, 0, "全国爱耳日"),
            new SolarHolidayStruct(3, 5, 0, "学雷锋纪念日"),
            new SolarHolidayStruct(3, 7, 0, "女生节"), 
            new SolarHolidayStruct(3, 8, 0, "妇女节"), 
            new SolarHolidayStruct(3, 12, 0, "植树节 孙中山逝世纪念日"), 
            new SolarHolidayStruct(3, 14, 0, "国际警察日 白色情人节"),
            new SolarHolidayStruct(3, 15, 0, "消费者权益日"),
            new SolarHolidayStruct(3, 17, 0, "中国国医节 国际航海日"),
            new SolarHolidayStruct(3, 20, 0, "春分"),
            new SolarHolidayStruct(3, 21, 0, "世界森林日 消除种族歧视国际日 世界儿歌日"),
            new SolarHolidayStruct(3, 22, 0, "世界水日"),
            new SolarHolidayStruct(3, 23, 0, "世界气象日"),
            new SolarHolidayStruct(3, 24, 0, "世界防治结核病日"),
            new SolarHolidayStruct(4, 1, 0, "愚人节"),
            new SolarHolidayStruct(4, 2, 0, "国际儿童图书日"),
            new SolarHolidayStruct(4, 5, 0, "复活节"),
            new SolarHolidayStruct(4, 7, 0, "世界卫生日"),
            new SolarHolidayStruct(4, 11, 0, "世界帕金森病日"),
            new SolarHolidayStruct(4, 21, 0, "全国企业家活动日"),
            new SolarHolidayStruct(4, 22, 0, "世界地球日"),
            new SolarHolidayStruct(4, 26, 0, "世界知识产权日 全国交通安全反思日"),
            new SolarHolidayStruct(5, 1, 1, "劳动节"), 
            new SolarHolidayStruct(5, 2, 1, "劳动节假日"),
            new SolarHolidayStruct(5, 3, 1, "劳动节假日"),
            new SolarHolidayStruct(5, 4, 0, "青年节"), 
            new SolarHolidayStruct(5, 8, 0, "世界红十字日"),
            new SolarHolidayStruct(5, 12, 0, "国际护士节"), 
            new SolarHolidayStruct(5, 17, 0, "同性恋非病化纪念日 世界电信日 全国助残日"), 
            new SolarHolidayStruct(5, 18, 0, "国际博物馆日"), 
            new SolarHolidayStruct(5, 31, 0, "世界无烟日"), 
            new SolarHolidayStruct(6, 1, 0, "国际儿童节"), 
            new SolarHolidayStruct(6, 5, 0, "世界环境保护日"),
            new SolarHolidayStruct(6, 6, 0, "拉拉节 全国爱眼日"),
            new SolarHolidayStruct(6, 14, 0, "国际献血者日"),
            new SolarHolidayStruct(6, 17, 0, "世界防治荒漠化和干旱日"),
            new SolarHolidayStruct(6, 20, 0, "世界难民日"),
            new SolarHolidayStruct(6, 21, 0, "夏至"),
            new SolarHolidayStruct(6, 23, 0, "国际奥林匹克日"),
            new SolarHolidayStruct(6, 26, 0, "国际禁毒日 国际宪章日"),
            new SolarHolidayStruct(7, 1, 0, "建党节 香港回归纪念 世界建筑日"),
            new SolarHolidayStruct(7, 2, 0, "国际体育记者日"),
            new SolarHolidayStruct(7, 6, 0, "国际接吻日"),
            new SolarHolidayStruct(7, 11, 0, "世界人口日"),
            new SolarHolidayStruct(8, 1, 0, "建军节"),
            new SolarHolidayStruct(8, 6, 0, "国际电影节"),
            new SolarHolidayStruct(8, 8, 0, "中国男子节 父亲节"),
            new SolarHolidayStruct(8, 15, 0, "抗日战争胜利纪念"),
            new SolarHolidayStruct(9, 8, 0, "国际扫盲日"),
            new SolarHolidayStruct(9, 9, 0, "逝世纪念"), 
            new SolarHolidayStruct(9, 10, 0, "教师节"),
            new SolarHolidayStruct(9, 16, 0, "国际臭氧层保护日"),
            new SolarHolidayStruct(9, 18, 0, "九·一八事变纪念日"),
            new SolarHolidayStruct(9, 20, 0, "国际爱牙日"),
            new SolarHolidayStruct(9, 21, 0, "国际和平日"),
            new SolarHolidayStruct(9, 22, 0, "世界无车日"),
            new SolarHolidayStruct(9, 23, 0, "秋分"),
            new SolarHolidayStruct(9, 27, 0, "世界旅游日"),
            new SolarHolidayStruct(9, 28, 0, "孔子诞辰"),
            new SolarHolidayStruct(10, 1, 1, "国庆节 国际音乐日"),
            new SolarHolidayStruct(10, 2, 1, "国庆节假日"),
            new SolarHolidayStruct(10, 3, 1, "国庆节假日"),
            new SolarHolidayStruct(10, 6, 0, "老人节"), 
            new SolarHolidayStruct(10, 10, 0, "辛亥革命纪念日"),
            new SolarHolidayStruct(10, 11, 0, "国家出柜日"),
            new SolarHolidayStruct(10, 14, 0, "世界标准日"),
            new SolarHolidayStruct(10, 15, 0, "国际盲人节"),
            new SolarHolidayStruct(10, 16, 0, "世界粮食日"),
            new SolarHolidayStruct(10, 24, 0, "联合国日"),
            new SolarHolidayStruct(10, 31, 0, "万圣节"),
            new SolarHolidayStruct(11, 10, 0, "世界青年节"),
            new SolarHolidayStruct(11, 11, 0, "双十一"),
            new SolarHolidayStruct(11, 12, 0, "孙中山诞辰纪念"), 
            new SolarHolidayStruct(11, 14, 0, "世界糖尿病日"),
            new SolarHolidayStruct(11, 17, 0, "国际大学生日"),
            new SolarHolidayStruct(12, 1, 0, "世界艾滋病日"), 
            new SolarHolidayStruct(12, 2, 0, "废除一切形式奴役世界日"),
            new SolarHolidayStruct(12, 3, 0, "世界残疾人日"), 
            new SolarHolidayStruct(12, 4, 0, "中国法制宣传日"), 
            new SolarHolidayStruct(12, 12, 0, "双十二"), 
            new SolarHolidayStruct(12, 20, 0, "澳门回归纪念"), 
            new SolarHolidayStruct(12, 21, 0, "国际篮球日"), 
            new SolarHolidayStruct(12, 22, 0, "冬至"), 
            new SolarHolidayStruct(12, 24, 0, "平安夜"), 
            new SolarHolidayStruct(12, 25, 0, "圣诞节"), 
            new SolarHolidayStruct(12, 26, 0, " 诞辰纪念")
           };
        #endregion

        #region 按农历计算的节日
        private static LunarHolidayStruct[] lHolidayInfo = new LunarHolidayStruct[]{
            new LunarHolidayStruct(1, 1, 1, "春节"), 
            new LunarHolidayStruct(1, 5, 0, "破五"), 
            new LunarHolidayStruct(1, 15, 0, "元宵节"), 
            new LunarHolidayStruct(2, 2, 0, "龙抬头"), 
            new LunarHolidayStruct(5, 5, 0, "端午节"), 
            new LunarHolidayStruct(6, 14, 0, "小暑"),
            new LunarHolidayStruct(6, 29, 0, "大暑"),
            new LunarHolidayStruct(7, 2, 0, "处暑"),
            new LunarHolidayStruct(7, 7, 0, "七夕情人节"),
            new LunarHolidayStruct(7, 15, 0, "中元节 盂兰盆节"), 
            new LunarHolidayStruct(8, 15, 0, "中秋节"), 
            new LunarHolidayStruct(9, 4, 0, "霜降"), 
            new LunarHolidayStruct(9, 9, 0, "重阳节"), 
            new LunarHolidayStruct(9, 19, 0, "立冬"), 
            new LunarHolidayStruct(10, 1, 0, "祭祖节"), 
            new LunarHolidayStruct(12, 8, 0, "腊八节"),
            new LunarHolidayStruct(12, 23, 0, "北方小年(扫房)"),
            new LunarHolidayStruct(12, 24, 0, "南方小年(掸尘)"),
            //new LunarHolidayStruct(12, 30, 0, "除夕")  //注意除夕需要其它方法进行计算
        };
        #endregion

        #region 按某月第几个星期几
        private static WeekHolidayStruct[] wHolidayInfo = new WeekHolidayStruct[]{
            new WeekHolidayStruct(5, 2, 1, "母亲节"), 
            new WeekHolidayStruct(5, 3, 1, "全国助残日"), 
            new WeekHolidayStruct(6, 3, 1, "父亲节"), 
            new WeekHolidayStruct(9, 3, 1, "世界清洁地球日"), 
            new WeekHolidayStruct(9, 3, 3, "国际和平日"), 
            new WeekHolidayStruct(9, 4, 1, "国际聋人节"), 
            new WeekHolidayStruct(10, 1, 2, "国际住房日"), 
            new WeekHolidayStruct(10, 1, 4, "国际减轻自然灾害日"),
            new WeekHolidayStruct(11, 4, 5, "感恩节")
        };
        #endregion
        #endregion

        #region 构造函数
        #region ChinaCalendar <用一个标准的公历日期来初使化>
        /// <summary>用一个标准的公历日期来初使化
        /// </summary>
        /// <param name="dt"></param>
        public ChineseCalendar(DateTime dt)
        {
            int i;
            int leap;
            int temp;
            int offset;
            CheckDateLimit(dt);
            _date = dt.Date;
            _datetime = dt;
            //农历日期计算部分
            leap = 0;
            temp = 0;
            TimeSpan ts = _date - ChineseCalendar.MinDay;//计算两天的基本差距
            offset = ts.Days;
            for (i = MinYear; i <= MaxYear; i++)
            {
                temp = GetChineseYearDays(i);  //求当年农历年天数
                if (offset - temp < 1)
                    break;
                else
                {
                    offset = offset - temp;
                }
            }
            _cYear = i;
            leap = GetChineseLeapMonth(_cYear);//计算该年闰哪个月
            //设定当年是否有闰月
            if (leap > 0)
            {
                _cIsLeapYear = true;
            }
            else
            {
                _cIsLeapYear = false;
            }
            _cIsLeapMonth = false;
            for (i = 1; i <= 12; i++)
            {
                //闰月
                if ((leap > 0) && (i == leap + 1) && (_cIsLeapMonth == false))
                {
                    _cIsLeapMonth = true;
                    i = i - 1;
                    temp = GetChineseLeapMonthDays(_cYear); //计算闰月天数
                }
                else
                {
                    _cIsLeapMonth = false;
                    temp = GetChineseMonthDays(_cYear, i);//计算非闰月天数
                }
                offset = offset - temp;
                if (offset <= 0) break;
            }
            offset = offset + temp;
            _cMonth = i;
            _cDay = offset;
        }
        #endregion

        #region ChinaCalendar <农历日期初始化>
        /// <summary>用农历的日期来初使化
        /// </summary>
        /// <param name="cy">农历年</param>
        /// <param name="cm">农历月</param>
        /// <param name="cd">农历日</param>
        /// <param name="LeapFlag">闰月标志</param>
        public ChineseCalendar(int cy, int cm, int cd, bool leapMonthFlag)
        {
            int i, leap, Temp, offset;
            CheckChineseDateLimit(cy, cm, cd, leapMonthFlag);
            _cYear = cy;
            _cMonth = cm;
            _cDay = cd;
            offset = 0;
            for (i = MinYear; i < cy; i++)
            {
                Temp = GetChineseYearDays(i); //求当年农历年天数
                offset = offset + Temp;
            }
            leap = GetChineseLeapMonth(cy);// 计算该年应该闰哪个月
            if (leap != 0)
            {
                this._cIsLeapYear = true;
            }
            else
            {
                this._cIsLeapYear = false;
            }
            if (cm != leap)
            {
                _cIsLeapMonth = false;  //当前日期并非闰月
            }
            else
            {
                _cIsLeapMonth = leapMonthFlag;  //使用用户输入的是否闰月月份
            }

            if ((_cIsLeapYear == false) || //当年没有闰月
                 (cm < leap)) //计算月份小于闰月     
            {
                #region ...
                for (i = 1; i < cm; i++)
                {
                    Temp = GetChineseMonthDays(cy, i);//计算非闰月天数
                    offset = offset + Temp;
                }
                //检查日期是否大于最大天
                if (cd > GetChineseMonthDays(cy, cm))
                {
                    throw new ChineseCalendarException("不合法的农历日期");
                }
                offset = offset + cd; //加上当月的天数
                #endregion
            }
            else   //是闰年,且计算月份大于或等于闰月
            {
                #region ...
                for (i = 1; i < cm; i++)
                {
                    Temp = GetChineseMonthDays(cy, i); //计算非闰月天数
                    offset = offset + Temp;
                }
                if (cm > leap) //计算月大于闰月
                {
                    Temp = GetChineseLeapMonthDays(cy);   //计算闰月天数
                    offset = offset + Temp;               //加上闰月天数
                    if (cd > GetChineseMonthDays(cy, cm))
                    {
                        throw new ChineseCalendarException("不合法的农历日期");
                    }
                    offset = offset + cd;
                }
                else  //计算月等于闰月
                {
                    //如果需要计算的是闰月,则应首先加上与闰月对应的普通月的天数
                    if (this._cIsLeapMonth == true) //计算月为闰月
                    {
                        Temp = GetChineseMonthDays(cy, cm); //计算非闰月天数
                        offset = offset + Temp;
                    }
                    if (cd > GetChineseLeapMonthDays(cy))
                    {
                        throw new ChineseCalendarException("不合法的农历日期");
                    }
                    offset = offset + cd;
                }
                #endregion
            }

            _date = MinDay.AddDays(offset);
        }
        #endregion
        #endregion

        #region 私有函数
        #region GetChineseMonthDays 传回农历 y年m月的总天数
        //传回农历 y年m月的总天数
        private int GetChineseMonthDays(int year, int month)
        {
            if (BitTest32((LunarDateArray[year - MinYear] & 0x0000FFFF), (16 - month)))
            {
                return 30;
            }
            else
            {
                return 29;
            }
        }
        #endregion

        #region GetChineseLeapMonth  传回农历 y年闰哪个月 1-12 , 没闰传回 0
        //传回农历 y年闰哪个月 1-12 , 没闰传回 0
        private int GetChineseLeapMonth(int year)
        {
            return LunarDateArray[year - MinYear] & 0xF;
        }
        #endregion

        #region GetChineseLeapMonthDays 传回农历 y年闰月的天数
        //传回农历 y年闰月的天数
        private int GetChineseLeapMonthDays(int year)
        {
            if (GetChineseLeapMonth(year) != 0)
            {
                if ((LunarDateArray[year - MinYear] & 0x10000) != 0)
                {
                    return 30;
                }
                else
                {
                    return 29;
                }
            }
            else
            {
                return 0;
            }
        }
        #endregion

        #region GetChineseYearDays 取农历年一年的天数
        /// <summary>取农历年一年的天数
        /// </summary>
        /// <param name="year"></param>
        /// <returns></returns>
        private int GetChineseYearDays(int year)
        {
            int i, f, sumDay, info;
            sumDay = 348; //29天 X 12个月
            i = 0x8000;
            info = LunarDateArray[year - MinYear] & 0x0FFFF;
            //计算12个月中有多少天为30天
            for (int m = 0; m < 12; m++)
            {
                f = info & i;
                if (f != 0)
                {
                    sumDay++;
                }
                i = i >> 1;
            }
            return sumDay + GetChineseLeapMonthDays(year);
        }
        #endregion

        #region GetChineseHour 获得当前时间的时辰
        /// <summary>获得当前时间的时辰
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        /// 
        private string GetChineseHour(DateTime dt)
        {
            int _hour, _minute, offset, i;
            int indexGan;
            //string ganHour, zhiHour;
            string tmpGan;
            //计算时辰的地支
            _hour = dt.Hour;    //获得当前时间小时
            _minute = dt.Minute;  //获得当前时间分钟
            if (_minute != 0) _hour += 1;
            offset = _hour / 2;
            if (offset >= 12) offset = 0;
            //zhiHour = zhiStr[offset].ToString();
            //计算天干
            TimeSpan ts = this._date - GanZhiStartDay;
            i = ts.Days % 60;
            indexGan = ((i % 10 + 1) * 2 - 1) % 10 - 1; //ganStr[i % 10] 为日的天干,(n*2-1) %10得出地支对应,n从1开始
            tmpGan = ganStr.Substring(indexGan) + ganStr.Substring(0, indexGan + 2);//凑齐12位
            //ganHour = ganStr[((i % 10 + 1) * 2 - 1) % 10 - 1].ToString();
            return tmpGan[offset].ToString() + zhiStr[offset].ToString();
        }
        #endregion


        #region CheckDateLimit  检查公历日期是否符合要求
        /// <summary>
        /// 检查公历日期是否符合要求
        /// </summary>
        /// <param name="dt"></param>
        private void CheckDateLimit(DateTime dt)
        {
            if ((dt < MinDay) || (dt > MaxDay))
            {
                throw new ChineseCalendarException("超出可转换的日期");
            }
        }
        #endregion


        #region CheckChineseDateLimit  检查农历日期是否合理
        /// <summary>
        /// 检查农历日期是否合理
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <param name="day"></param>
        /// <param name="leapMonth"></param>
        private void CheckChineseDateLimit(int year, int month, int day, bool leapMonth)
        {
            if ((year < MinYear) || (year > MaxYear))
            {
                throw new ChineseCalendarException("非法农历日期");
            }
            if ((month < 1) || (month > 12))
            {
                throw new ChineseCalendarException("非法农历日期");
            }
            if ((day < 1) || (day > 30)) //中国的月最多30天
            {
                throw new ChineseCalendarException("非法农历日期");
            }
            int leap = GetChineseLeapMonth(year);// 计算该年应该闰哪个月
            if ((leapMonth == true) && (month != leap))
            {
                throw new ChineseCalendarException("非法农历日期");
            }

        }
        #endregion


        #region ConvertNumToChineseNum  将0-9转成汉字形式
        /// <summary>
        /// 将0-9转成汉字形式
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        private string ConvertNumToChineseNum(char n)
        {
            if ((n < '0') || (n > '9')) return "";
            switch (n)
            {
                case '0':
                    return HZNum[0].ToString();
                case '1':
                    return HZNum[1].ToString();
                case '2':
                    return HZNum[2].ToString();
                case '3':
                    return HZNum[3].ToString();
                case '4':
                    return HZNum[4].ToString();
                case '5':
                    return HZNum[5].ToString();
                case '6':
                    return HZNum[6].ToString();
                case '7':
                    return HZNum[7].ToString();
                case '8':
                    return HZNum[8].ToString();
                case '9':
                    return HZNum[9].ToString();
                default:
                    return "";
            }
        }
        #endregion


        #region BitTest32 测试某位是否为真
        /// <summary>测试某位是否为真
        /// </summary>
        /// <param name="num"></param>
        /// <param name="bitpostion"></param>
        /// <returns></returns>
        private bool BitTest32(int num, int bitpostion)
        {
            if ((bitpostion > 31) || (bitpostion < 0))
                throw new Exception("Error Param: bitpostion[0-31]:" + bitpostion.ToString());
            int bit = 1 << bitpostion;
            if ((num & bit) == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        #endregion


        #region ConvertDayOfWeek  将星期几转成数字表示
        /// <summary>将星期几转成数字表示
        /// </summary>
        /// <param name="dayOfWeek"></param>
        /// <returns></returns>
        private int ConvertDayOfWeek(DayOfWeek dayOfWeek)
        {
            switch (dayOfWeek)
            {
                case DayOfWeek.Sunday:
                    return 1;
                case DayOfWeek.Monday:
                    return 2;
                case DayOfWeek.Tuesday:
                    return 3;
                case DayOfWeek.Wednesday:
                    return 4;
                case DayOfWeek.Thursday:
                    return 5;
                case DayOfWeek.Friday:
                    return 6;
                case DayOfWeek.Saturday:
                    return 7;
                default:
                    return 0;
            }
        }
        #endregion


        #region CompareWeekDayHoliday  比较当天是不是指定的第周几
        /// <summary>比较当天是不是指定的第周几
        /// </summary>
        /// <param name="date"></param>
        /// <param name="month"></param>
        /// <param name="week"></param>
        /// <param name="day"></param>
        /// <returns></returns>
        private bool CompareWeekDayHoliday(DateTime date, int month, int week, int day)
        {
            bool ret = false;
            if (date.Month == month) //月份相同
            {
                if (ConvertDayOfWeek(date.DayOfWeek) == day) //星期几相同
                {
                    DateTime firstDay = new DateTime(date.Year, date.Month, 1);//生成当月第一天
                    int i = ConvertDayOfWeek(firstDay.DayOfWeek);
                    int firWeekDays = 7 - ConvertDayOfWeek(firstDay.DayOfWeek) + 1; //计算第一周剩余天数
                    if (i > day)
                    {
                        if ((week - 1) * 7 + day + firWeekDays == date.Day)
                        {
                            ret = true;
                        }
                    }
                    else
                    {
                        if (day + firWeekDays + (week - 2) * 7 == date.Day)
                        {
                            ret = true;
                        }
                    }
                }
            }
            return ret;
        }
        #endregion

        #endregion

        #region  属性

        #region 节日
        #region ChineseCalendarHoliday 计算中国农历节日
        /// <summary>计算中国农历节日
        /// </summary>
        public string ChineseCalendarHoliday
        {
            get
            {
                string tempStr = "";
                if (this._cIsLeapMonth == false) //闰月不计算节日
                {
                    foreach (LunarHolidayStruct lh in lHolidayInfo)
                    {
                        if ((lh.Month == this._cMonth) && (lh.Day == this._cDay))
                        {
                            tempStr = lh.HolidayName;
                            break;
                        }
                    }
                    //对除夕进行特别处理
                    if (this._cMonth == 12)
                    {
                        int i = GetChineseMonthDays(this._cYear, 12); //计算当年农历12月的总天数
                        if (this._cDay == i) //如果为最后一天
                        {
                            tempStr = "除夕";
                        }
                    }
                }
                return tempStr;
            }
        }
        #endregion

        #region WeekDayHoliday 按某月第几周第几日计算的节日
        /// <summary>按某月第几周第几日计算的节日
        /// </summary>
        public string WeekDayHoliday
        {
            get
            {
                string tempStr = "";
                foreach (WeekHolidayStruct wh in wHolidayInfo)
                {
                    if (CompareWeekDayHoliday(_date, wh.Month, wh.WeekAtMonth, wh.WeekDay))
                    {
                        tempStr = wh.HolidayName;
                        break;
                    }
                }
                return tempStr;
            }
        }
        #endregion

        #region DateHoliday 按公历日计算的节日
        /// <summary>按公历日计算的节日
        /// </summary>
        public string DateHoliday
        {
            get
            {
                string tempStr = "";
                foreach (SolarHolidayStruct sh in sHolidayInfo)
                {
                    if ((sh.Month == _date.Month) && (sh.Day == _date.Day))
                    {
                        tempStr = sh.HolidayName;
                        break;
                    }
                }
                return tempStr;
            }
        }
        #endregion

        #endregion

        #region 公历日期
        #region Date 取对应的公历日期
        /// <summary>取对应的公历日期
        /// </summary>
        public DateTime Date
        {
            get { return _date; }
            set { _date = value; }
        }
        #endregion

        #region WeekDay 取星期几
        /// <summary>取星期几
        /// </summary>
        public DayOfWeek WeekDay
        {
            get { return _date.DayOfWeek; }
        }
        #endregion

        #region WeekDayStr 周几的字符
        /// <summary>周几的字符
        /// </summary>
        public string WeekDayStr
        {
            get
            {
                switch (_date.DayOfWeek)
                {
                    case DayOfWeek.Sunday:
                        return "星期日";
                    case DayOfWeek.Monday:
                        return "星期一";
                    case DayOfWeek.Tuesday:
                        return "星期二";
                    case DayOfWeek.Wednesday:
                        return "星期三";
                    case DayOfWeek.Thursday:
                        return "星期四";
                    case DayOfWeek.Friday:
                        return "星期五";
                    default:
                        return "星期六";
                }
            }
        }
        #endregion

        #region DateString 公历日期中文表示法 如一九九七年七月一日
        /// <summary>公历日期中文表示法 如一九九七年七月一日
        /// </summary>
        public string DateString
        {
            get
            {
                return "公元" + this._date.ToLongDateString();
            }
        }
        #endregion

        #region IsLeapYear当前是否公历闰年
        /// <summary>当前是否公历闰年
        /// </summary>
        public bool IsLeapYear
        {
            get
            {
                return DateTime.IsLeapYear(this._date.Year);
            }
        }
        #endregion

        #region ChineseConstellation 28星宿计算
        /// <summary>28星宿计算
        /// </summary>
        public string ChineseConstellation
        {
            get
            {
                int offset = 0;
                int modStarDay = 0;
                TimeSpan ts = this._date - ChineseConstellationReferDay;
                offset = ts.Days;
                modStarDay = offset % 28;
                return (modStarDay >= 0 ? _chineseConstellationName[modStarDay] : _chineseConstellationName[27 + modStarDay]);
            }
        }
        #endregion

        #region ChineseHour 时辰
        /// <summary>时辰
        /// </summary>
        public string ChineseHour
        {
            get
            {
                return GetChineseHour(_datetime);
            }
        }
        #endregion

        #endregion

        #region 农历日期
        #region IsChineseLeapMonth 是否闰月
        /// <summary>是否闰月
        /// </summary>
        public bool IsChineseLeapMonth
        {
            get { return this._cIsLeapMonth; }
        }
        #endregion

        #region IsChineseLeapYear 当年是否有闰月
        /// <summary> 当年是否有闰月
        /// </summary>
        public bool IsChineseLeapYear
        {
            get
            {
                return this._cIsLeapYear;
            }
        }
        #endregion

        #region ChineseDay 农历日
        /// <summary>农历日
        /// </summary>
        public int ChineseDay
        {
            get { return this._cDay; }
        }
        #endregion

        #region ChineseDayString农历日中文表示
        /// <summary>农历日中文表示
        /// </summary>
        public string ChineseDayString
        {
            get
            {
                switch (this._cDay)
                {
                    case 0:
                        return "";
                    case 10:
                        return "初十";
                    case 20:
                        return "二十";
                    case 30:
                        return "三十";
                    default:
                        return nStr2[(int)(_cDay / 10)].ToString() + nStr1[_cDay % 10].ToString();
                }
            }
        }
        #endregion

        #region ChineseMonth 农历的月份
        /// <summary>农历的月份
        /// </summary>
        public int ChineseMonth
        {
            get { return this._cMonth; }
        }
        #endregion

        #region ChineseMonthString 农历月份字符串
        /// <summary>农历月份字符串
        /// </summary>
        public string ChineseMonthString
        {
            get
            {
                return _monthString[this._cMonth];
            }
        }
        #endregion

        #region ChineseYear 取农历年份
        /// <summary>取农历年份
        /// </summary>
        public int ChineseYear
        {
            get { return this._cYear; }
        }
        #endregion

        #region ChineseYearString 取农历年字符串如,一九九七年
        /// <summary>取农历年字符串如,一九九七年
        /// </summary>
        public string ChineseYearString
        {
            get
            {
                string tempStr = "";
                string num = this._cYear.ToString();
                for (int i = 0; i < 4; i++)
                {
                    tempStr += ConvertNumToChineseNum(num[i]);
                }
                return tempStr + "年";
            }
        }
        #endregion

        #region ChineseDateString 取农历日期表示法:农历一九九七年正月初五
        /// <summary>取农历日期表示法:农历一九九七年正月初五
        /// </summary>
        public string ChineseDateString
        {
            get
            {
                if (this._cIsLeapMonth == true)
                {
                    return "农历" + ChineseYearString + "闰" + ChineseMonthString + ChineseDayString;
                }
                else
                {
                    return "农历" + ChineseYearString + ChineseMonthString + ChineseDayString;
                }
            }
        }
        #endregion

        #region ChineseTwentyFourDay 定气法计算二十四节气,二十四节气是按地球公转来计算的,并非是阴历计算的
        /// <summary>定气法计算二十四节气,二十四节气是按地球公转来计算的,并非是阴历计算的
        /// </summary>
        /// <remarks>
        /// 节气的定法有两种。古代历法采用的称为"恒气",即按时间把一年等分为24份,
        /// 每一节气平均得15天有余,所以又称"平气"。现代农历采用的称为"定气",即
        /// 按地球在轨道上的位置为标准,一周360°,两节气之间相隔15°。由于冬至时地
        /// 球位于近日点附近,运动速度较快,因而太阳在黄道上移动15°的时间不到15天。
        /// 夏至前后的情况正好相反,太阳在黄道上移动较慢,一个节气达16天之多。采用
        /// 定气时可以保证春、秋两分必然在昼夜平分的那两天。
        /// </remarks>
        public string ChineseTwentyFourDay
        {
            get
            {
                DateTime baseDateAndTime = new DateTime(1900, 1, 6, 2, 5, 0); //#1/6/1900 2:05:00 AM#
                DateTime newDate;
                double num;
                int y;
                string tempStr = "";
                y = this._date.Year;
                for (int i = 1; i <= 24; i++)
                {
                    num = 525948.76 * (y - 1900) + sTermInfo[i - 1];
                    newDate = baseDateAndTime.AddMinutes(num);//按分钟计算
                    if (newDate.DayOfYear == _date.DayOfYear)
                    {
                        tempStr = SolarTerm[i - 1];
                        break;
                    }
                }
                return tempStr;
            }
        }
        //当前日期前一个最近节气
        public string ChineseTwentyFourPrevDay
        {
            get
            {
                DateTime baseDateAndTime = new DateTime(1900, 1, 6, 2, 5, 0); //#1/6/1900 2:05:00 AM#
                DateTime newDate;
                double num;
                int y;
                string tempStr = "";
                y = this._date.Year;
                for (int i = 24; i >= 1; i--)
                {
                    num = 525948.76 * (y - 1900) + sTermInfo[i - 1];
                    newDate = baseDateAndTime.AddMinutes(num);//按分钟计算
                    if (newDate.DayOfYear < _date.DayOfYear)
                    {
                        tempStr = string.Format("{0}[{1}]", SolarTerm[i - 1], newDate.ToString("yyyy-MM-dd"));
                        break;
                    }
                }
                return tempStr;
            }
        }
        //当前日期后一个最近节气
        public string ChineseTwentyFourNextDay
        {
            get
            {
                DateTime baseDateAndTime = new DateTime(1900, 1, 6, 2, 5, 0); //#1/6/1900 2:05:00 AM#
                DateTime newDate;
                double num;
                int y;
                string tempStr = "";
                y = this._date.Year;
                for (int i = 1; i <= 24; i++)
                {
                    num = 525948.76 * (y - 1900) + sTermInfo[i - 1];
                    newDate = baseDateAndTime.AddMinutes(num);//按分钟计算
                    if (newDate.DayOfYear > _date.DayOfYear)
                    {
                        tempStr = string.Format("{0}[{1}]", SolarTerm[i - 1], newDate.ToString("yyyy-MM-dd"));
                        break;
                    }
                }
                return tempStr;
            }
        }
        #endregion
        #endregion

        #region 星座
        #region Constellation 计算指定日期的星座序号
        /// <summary>计算指定日期的星座序号 
        /// </summary>
        /// <returns></returns>
        public string Constellation
        {
            get
            {
                int index = 0;
                int y, m, d;
                y = _date.Year;
                m = _date.Month;
                d = _date.Day;
                y = m * 100 + d;
                if (((y >= 321) && (y <= 419))) { index = 0; }
                else if ((y >= 420) && (y <= 520)) { index = 1; }
                else if ((y >= 521) && (y <= 620)) { index = 2; }
                else if ((y >= 621) && (y <= 722)) { index = 3; }
                else if ((y >= 723) && (y <= 822)) { index = 4; }
                else if ((y >= 823) && (y <= 922)) { index = 5; }
                else if ((y >= 923) && (y <= 1022)) { index = 6; }
                else if ((y >= 1023) && (y <= 1121)) { index = 7; }
                else if ((y >= 1122) && (y <= 1221)) { index = 8; }
                else if ((y >= 1222) || (y <= 119)) { index = 9; }
                else if ((y >= 120) && (y <= 218)) { index = 10; }
                else if ((y >= 219) && (y <= 320)) { index = 11; }
                else { index = 0; }
                return _constellationName[index];
            }
        }
        #endregion
        #endregion

        #region 属相
        #region Animal 计算属相的索引
        /// <summary>计算属相的索引,注意虽然属相是以农历年来区别的,但是目前在实际使用中是按公历来计算的
        /// 鼠年为1,其它类推
        /// </summary>
        public int Animal
        {
            get
            {
                int offset = _date.Year - AnimalStartYear;
                return (offset % 12) + 1;
            }
        }
        #endregion

        #region AnimalString 取属相字符串
        /// <summary>取属相字符串
        /// </summary>
        public string AnimalString
        {
            get
            {
                int offset = _date.Year - AnimalStartYear; //阳历计算
                //int offset = this._cYear - AnimalStartYear; 农历计算
                return animalStr[offset % 12].ToString();
            }
        }
        #endregion
        #endregion

        #region 天干地支
        #region GanZhiYearString 取农历年的干支表示法如 乙丑年
        /// <summary>取农历年的干支表示法如 乙丑年
        /// </summary>
        public string GanZhiYearString
        {
            get
            {
                string tempStr;
                int i = (this._cYear - GanZhiStartYear) % 60; //计算干支
                tempStr = ganStr[i % 10].ToString() + zhiStr[i % 12].ToString() + "年";
                return tempStr;
            }
        }
        #endregion

        #region GanZhiMonthString 取干支的月表示字符串,注意农历的闰月不记干支
        /// <summary>取干支的月表示字符串,注意农历的闰月不记干支
        /// </summary>
        public string GanZhiMonthString
        {
            get
            {
                //每个月的地支总是固定的,而且总是从寅月开始
                int zhiIndex;
                string zhi;
                if (this._cMonth > 10)
                {
                    zhiIndex = this._cMonth - 10;
                }
                else
                {
                    zhiIndex = this._cMonth + 2;
                }
                zhi = zhiStr[zhiIndex - 1].ToString();
                //根据当年的干支年的干来计算月干的第一个
                int ganIndex = 1;
                string gan;
                int i = (this._cYear - GanZhiStartYear) % 60; //计算干支
                switch (i % 10)
                {
                    #region ...
                    case 0: //甲
                        ganIndex = 3;
                        break;
                    case 1: //乙
                        ganIndex = 5;
                        break;
                    case 2: //丙
                        ganIndex = 7;
                        break;
                    case 3: //丁
                        ganIndex = 9;
                        break;
                    case 4: //戊
                        ganIndex = 1;
                        break;
                    case 5: //己
                        ganIndex = 3;
                        break;
                    case 6: //庚
                        ganIndex = 5;
                        break;
                    case 7: //辛
                        ganIndex = 7;
                        break;
                    case 8: //壬
                        ganIndex = 9;
                        break;
                    case 9: //癸
                        ganIndex = 1;
                        break;
                    #endregion
                }
                gan = ganStr[(ganIndex + this._cMonth - 2) % 10].ToString();
                return gan + zhi + "月";
            }
        }
        #endregion

        #region GanZhiDayString 取干支日表示法
        /// <summary>取干支日表示法
        /// </summary>
        public string GanZhiDayString
        {
            get
            {
                int i, offset;
                TimeSpan ts = this._date - GanZhiStartDay;
                offset = ts.Days;
                i = offset % 60;
                return ganStr[i % 10].ToString() + zhiStr[i % 12].ToString() + "日";
            }
        }
        #endregion

        #region GanZhiDateString 取当前日期的干支表示法如 甲子年乙丑月丙庚日
        /// <summary>取当前日期的干支表示法如 甲子年乙丑月丙庚日
        /// </summary>
        public string GanZhiDateString
        {
            get
            {
                return GanZhiYearString + GanZhiMonthString + GanZhiDayString;
            }
        }
        #endregion
        #endregion

        #endregion

        #region 方法

        #region 取下一天
        /// <summary>取下一天
        /// </summary>
        /// <returns></returns>
        public ChineseCalendar NextDay()
        {
            DateTime nextDay = _date.AddDays(1);
            return new ChineseCalendar(nextDay);
        }
        #endregion

        #region 取前一天
        /// <summary>取前一天
        /// </summary>
        /// <returns></returns>
        public ChineseCalendar PervDay()
        {
            DateTime pervDay = _date.AddDays(-1);
            return new ChineseCalendar(pervDay);
        }
        #endregion

        #endregion
    }

    #endregion


}

5.6 MemoDAL

MemoDAL.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using MemoModel;
using System.Diagnostics;

namespace MemoDAL
{
    public class MemoDAL
    {

        static SqlConnection conn;

        //其实我们应该把两个getEvent方法抽象成一个【执行sql语句的方法】,
        //从BLL层调用DAL层,传过来sql语句
        //然后用【执行sql语句的方法】去执行它
        //再返回一个List<MyEvent>给BLL

        /// <summary>根据日期获得当天备忘录
        /// </summary>
        /// <param name="dateTime">日期</param>
        /// <returns></returns>
        public List<MyEvent> getEvent(DateTime dateTime)
        {
            try
            {
                List<MyEvent> list = new List<MyEvent>();
                conn = new SqlConnection("integrated security=sspi;database=memorandum;server=(local)");
                conn.Open();
                String tmpDay = dateTime.ToString("yyyy-MM-dd");
                String tmpTable = "event" + dateTime.ToString("yyyy");

                String sqlcmd = "select *  from " + tmpTable + " where startDate='" + tmpDay + "'";
                SqlCommand cmd = new SqlCommand(sqlcmd, conn);

                #region  判断表是否存在
                SqlCommand checkIfTableExistsCmd = conn.CreateCommand();//用来判断表是否存在的sql命令
                checkIfTableExistsCmd.CommandText = "if object_id( '" + tmpTable + " ') is not null select 1 else select 0";

                if ((int)checkIfTableExistsCmd.ExecuteScalar() == 0)
                {
                    return list;//返回一个空的list
                }
                #endregion

                //Debug.WriteLine("-----dal test:"+sqlcmd);

                SqlDataAdapter data = new SqlDataAdapter();
                data.SelectCommand = cmd;
                DataSet ds = new DataSet();

                ds.Clear();
                Debug.WriteLine("---表名:" + tmpTable);
                data.Fill(ds, tmpTable);

                DataTable table = ds.Tables[tmpTable];

                MyEvent e;

                String startDate1 = "2018-12-08";
                String startTime1 = "20:00:00";

                DateTime startTime = DateTime.Parse(startDate1 + " " + startTime1);
                Debug.WriteLine("-----dal test:" + startTime.ToString("yyyy-MM-dd HH:mm:ss"));

                //String endTime1 = "2018-12-08 20:00:00";
                //DateTime endTime = DateTime.Parse(endTime1);
                //Debug.WriteLine("-----dal test:" + endTime.ToString("yyyy-MM-dd HH:mm:ss"));




                for (int i = 0; i < table.Rows.Count; i++)
                {
                    String eventId = table.Rows[i]["eventId"].ToString();
                    String owner = table.Rows[i]["owner"].ToString();
                    String eventName = table.Rows[i]["eventName"].ToString();
                    String place = table.Rows[i]["place"].ToString();

                    String startDate1 = table.Rows[i]["startDate"].ToString();
                    String startTime1 = table.Rows[i]["startTime"].ToString();

                    DateTime startTime = DateTime.Parse(startDate1 + " " + startTime1);

                    String endTime1 = table.Rows[i]["endTime"].ToString();
                    DateTime endTime = DateTime.Parse(endTime1);

                    String remindTime1 = table.Rows[i]["remindTime"].ToString();
                    DateTime remindTime = DateTime.Parse(remindTime1);

                    String eventNote = table.Rows[i]["eventNote"].ToString();

                    e = new MyEvent(eventName, eventId, owner, place, startTime, startTime, startTime, eventNote);
                    list.Add(e);
                }
                conn.Close();

                return list;

            }
            catch (Exception ex)
            {
                Debug.WriteLine("dal getDayEvent 出错:");
                Debug.WriteLine(ex.Message);
                return null;
            }

        }


        /// <summary>根据年份获取一年的备忘录
        /// </summary>
        /// <param name="year">年</param>
        /// <returns></returns>
        public List<MyEvent> getEvent(String year)
        {
            List<MyEvent> list = new List<MyEvent>();

            try
            {
                conn = new SqlConnection("integrated security=sspi;database=memorandum;server=(local)");
                conn.Open();
                String tmpTable = "event" + year;

                String sqlcmd = "select * from " + tmpTable + " where startDate like '%" + year + "%'";

                SqlCommand cmd = new SqlCommand(sqlcmd, conn);

                #region  判断表是否存在
                SqlCommand checkIfTableExistsCmd = conn.CreateCommand();//用来判断表是否存在的sql命令
                checkIfTableExistsCmd.CommandText = "if object_id( '" + tmpTable + " ') is not null select 1 else select 0";

                if ((int)checkIfTableExistsCmd.ExecuteScalar() == 0)
                {
                    return list;//返回一个空的list
                }
                #endregion

                SqlDataAdapter data = new SqlDataAdapter();
                data.SelectCommand = cmd;
                DataSet ds = new DataSet();

                ds.Clear();
                Debug.WriteLine("-----dal test:" + sqlcmd);
                data.Fill(ds, tmpTable);


                DataTable table = ds.Tables[tmpTable];

                MyEvent e;

                //        String startDate1 = "2018-12-08";
                //        String startTime1 = "20:00:00";

                //        DateTime startTime = DateTime.Parse(startDate1 + " " + startTime1);
                //        Debug.WriteLine("-----dal test:" + startTime.ToString("yyyy-MM-dd HH:mm:ss"));

                //        String endTime1 = "2018-12-08 20:00:00";
                //        DateTime endTime = DateTime.Parse(endTime1);
                //        Debug.WriteLine("-----dal test:" + endTime.ToString("yyyy-MM-dd HH:mm:ss"));


                for (int i = 0; i < table.Rows.Count; i++)
                {
                    String eventId = table.Rows[i]["eventId"].ToString();
                    String owner = table.Rows[i]["owner"].ToString();
                    String eventName = table.Rows[i]["eventName"].ToString();
                    String place = table.Rows[i]["place"].ToString();

                    String startDate1 = table.Rows[i]["startDate"].ToString();
                    String startTime1 = table.Rows[i]["startTime"].ToString();

                    DateTime startTime = DateTime.Parse(startDate1 + " " + startTime1);

                    String endTime1 = table.Rows[i]["endTime"].ToString();
                    DateTime endTime = DateTime.Parse(endTime1);

                    String remindTime1 = table.Rows[i]["remindTime"].ToString();
                    DateTime remindTime = DateTime.Parse(remindTime1);

                    String eventNote = table.Rows[i]["eventNote"].ToString();

                    e = new MyEvent(eventName, eventId, owner, place, startTime, startTime, startTime, eventNote);
                    list.Add(e);
                }
                conn.Close();

                return list;

            }
            catch (Exception ex)
            {
                Debug.WriteLine("dal getEvent 出错:");
                Debug.WriteLine(ex.Message);
                return list;
            }

        }

        #region 被弃用的addEvent方法
        / <summary>添加事件到数据库表中
        / </summary>
        / <param name="myevent">要添加的备忘录事件</param>
        //public void addEvent(MyEvent myevent)
        //{
        //    #region 连接数据库
        //    try
        //    {
        //        conn = new SqlConnection("integrated security=sspi;database=memorandum;server=(local)");
        //        conn.Open();
        //    }
        //    catch (Exception ex)
        //    {
        //        Debug.WriteLine("--数据库连接出错  出错:");
        //        Debug.WriteLine(ex.Message);
        //    }
        //    #endregion

        //    SqlCommand cmd = new SqlCommand();
        //    cmd.Connection = conn;

        //    #region 从传入的MyEvent中提取出要保存的每项信息,如备忘事件名称等
        //    string eventId = myevent.getEventId();
        //    string owner = myevent.getOwner();
        //    string eventName = myevent.getEventName();
        //    string place = myevent.getPlace();
        //    string startDate = myevent.getStartTime().ToString("yyyy-MM-dd");
        //    string startTime = myevent.getStartTime().ToString("HH:mm:ss");
        //    DateTime remindTime = myevent.getRemindTime();
        //    DateTime endTime = myevent.getEndTime();
        //    string eventNote = myevent.getEventNote();
        //    #endregion

        //    //Debug.WriteLine("---调试:由startTime生成的id:  " + eventId);
        //    //Debug.WriteLine("---调试:startTime  " + startDate);

        //    String tmpTable = "event" + startDate.Substring(0, 4); //获取表名, 如:event2018

        //    //构建sql语句,然后添加参数类型和长度
        //    cmd.CommandText = "Insert into " + tmpTable + "(eventId,owner,eventName,place,startDate,startTime,endTime,remindTime,eventNote)"
        //                           + " Values(@eventId,@owner,@eventName,@place,@startDate,@startTime,@endTime,@remindTime,@eventNote)";

        //    #region 添加参数类型和长度
        //    cmd.Parameters.Add("@eventId", SqlDbType.VarChar, 15);
        //    cmd.Parameters.Add("@owner", SqlDbType.VarChar, 20);
        //    cmd.Parameters.Add("@eventName", SqlDbType.VarChar, 20);
        //    cmd.Parameters.Add("@place", SqlDbType.VarChar, 30);
        //    cmd.Parameters.Add("@startDate", SqlDbType.VarChar, 11);
        //    cmd.Parameters.Add("@startTime", SqlDbType.VarChar, 8);
        //    cmd.Parameters.Add("@endTime", SqlDbType.DateTime);
        //    cmd.Parameters.Add("@remindTime", SqlDbType.DateTime);
        //    cmd.Parameters.Add("@eventNote", SqlDbType.VarChar, 200);
        //    #endregion

        //    #region 为参数赋值
        //    cmd.Parameters["@eventId"].Value = eventId;
        //    cmd.Parameters["@owner"].Value = owner;
        //    cmd.Parameters["@eventName"].Value = eventName;
        //    cmd.Parameters["@place"].Value = place;
        //    cmd.Parameters["@startDate"].Value = startDate;
        //    cmd.Parameters["@startTime"].Value = startTime;
        //    cmd.Parameters["@endTime"].Value = endTime;
        //    cmd.Parameters["@remindTime"].Value = remindTime;
        //    cmd.Parameters["@eventNote"].Value = eventNote;
        //    #endregion

        //    //Debug.WriteLine("--调试:表名" + tmpTable);
        //    //Debug.WriteLine("--调试:sql语句:  " + cmd.CommandText);

        //    cmd.Prepare();//编译
        //    cmd.ExecuteNonQuery();//执行,进行更新
        //    conn.Close(); //关闭连接

        //}
        #endregion

        /// <summary>添加事件到数据库表中
        /// </summary>
        /// <param name="list">要添加的备忘录事件列表</param>
        public void addEvent(List<MyEvent> list)
        {
            #region 连接数据库
            try
            {
                conn = new SqlConnection("integrated security=sspi;database=memorandum;server=(local)");
                conn.Open();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("--数据库连接出错  出错:");
                Debug.WriteLine(ex.Message);
            }
            #endregion

            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            SqlCommand checkIfTableExistsCmd = conn.CreateCommand();//用来判断表是否存在的sql命令
            
            MyEvent myevent;
            #region MyEvent中要保存的每项信息,如备忘事件名称等
            string eventId;
            string owner;
            string eventName;
            string place;
            string startDate;
            string startTime;
            DateTime remindTime;
            DateTime endTime;
            string eventNote;
            #endregion

            for (int i = 0; i < list.Count; i++)
            {
                myevent = ((MyEvent)list[i]);

                #region MyEvent中要保存的每项信息,如备忘事件名称等
                eventId = myevent.getEventId();
                owner = myevent.getOwner();
                eventName = myevent.getEventName();
                place = myevent.getPlace();
                startDate = myevent.getStartTime().ToString("yyyy-MM-dd");
                startTime = myevent.getStartTime().ToString("HH:mm:ss");
                remindTime = myevent.getRemindTime();
                endTime = myevent.getEndTime();
                eventNote = myevent.getEventNote();
                #endregion

                //Debug.WriteLine("---调试:由startTime生成的id:  " + eventId);
                //Debug.WriteLine("---调试:startTime  " + startDate);

                String tmpTable = "event" + startDate.Substring(0, 4); //获取表名, 如:event2018

                checkIfTableExistsCmd.CommandText = "if object_id( '" + tmpTable + " ') is not null select 1 else select 0";

                if ((int)checkIfTableExistsCmd.ExecuteScalar() == 0)
                {
                    checkIfTableExistsCmd.CommandText = @"CREATE TABLE "+tmpTable+
                        "(eventId varchar(15),"+
                        "owner varchar(20),"+
                        "eventName varchar(20),"+
                        "place varchar(30),"+
                        "startDate varchar(11),"+
                        "startTime varchar(8),"+
                        "endTime datetime,"+
                        "remindTime datetime,"+
                        "eventNote varchar(200))";
                    checkIfTableExistsCmd.ExecuteNonQuery();
                }
                Debug.WriteLine("----建表成功:" + tmpTable);
                //构建sql语句,然后添加参数类型和长度
                cmd.CommandText = "Insert into " + tmpTable + "(eventId,owner,eventName,place,startDate,startTime,endTime,remindTime,eventNote)"
                                       + " Values(@eventId,@owner,@eventName,@place,@startDate,@startTime,@endTime,@remindTime,@eventNote)";

                cmd.Parameters.Clear();//清空原来的参数,不然会报错

                #region 添加参数类型和长度
                cmd.Parameters.Add("@eventId", SqlDbType.VarChar, 15);
                cmd.Parameters.Add("@owner", SqlDbType.VarChar, 20);
                cmd.Parameters.Add("@eventName", SqlDbType.VarChar, 20);
                cmd.Parameters.Add("@place", SqlDbType.VarChar, 30);
                cmd.Parameters.Add("@startDate", SqlDbType.VarChar, 11);
                cmd.Parameters.Add("@startTime", SqlDbType.VarChar, 8);
                cmd.Parameters.Add("@endTime", SqlDbType.DateTime);
                cmd.Parameters.Add("@remindTime", SqlDbType.DateTime);
                cmd.Parameters.Add("@eventNote", SqlDbType.VarChar, 200);
                #endregion

                #region 为参数赋值
                cmd.Parameters["@eventId"].Value = eventId;
                cmd.Parameters["@owner"].Value = owner;
                cmd.Parameters["@eventName"].Value = eventName;
                cmd.Parameters["@place"].Value = place;
                cmd.Parameters["@startDate"].Value = startDate;
                cmd.Parameters["@startTime"].Value = startTime;
                cmd.Parameters["@endTime"].Value = endTime;
                cmd.Parameters["@remindTime"].Value = remindTime;
                cmd.Parameters["@eventNote"].Value = eventNote;
                #endregion

                //Debug.WriteLine("--调试:表名" + tmpTable);
                //Debug.WriteLine("--调试:sql语句:  " + cmd.CommandText);

                cmd.Prepare();//编译
                cmd.ExecuteNonQuery();//执行,进行更新
            }

            conn.Close(); //关闭连接

        }


        /// <summary>根据传入的事件ID,找到表,删掉事件
        /// </summary>
        /// <param name="myEvent">要删除的备忘录事件</param>
        /// <returns></returns>
        public void deleteEvent(MyEvent myEvent)
        {

            try
            {
                conn = new SqlConnection("integrated security=sspi;database=memorandum;server=(local)");
                conn.Open();

                string year = myEvent.getStartTime().ToString("yyyy");

                String tmpTable = "event" + year;

                String sqlcmd = "delete from " + tmpTable + " where eventId = '" + myEvent.getEventId() + "' and owner = '" + myEvent.getOwner() + "'";
                SqlCommand cmd = new SqlCommand(sqlcmd, conn);

                cmd.ExecuteNonQuery();
                conn.Close();

            }
            catch (Exception ex)
            {
                Debug.WriteLine("dal deleteEvent 出错:");
                Debug.WriteLine(ex.Message);

            }

        }

        /// <summary>根据传入的事件ID,找到表,删掉事件
        /// </summary>
        /// <param name="list">要删除的列表</param>
        /// <returns></returns>
        public void deleteEvent(List<MyEvent> list)
        {
            try
            {
                conn = new SqlConnection("integrated security=sspi;database=memorandum;server=(local)");
                conn.Open();

                MyEvent myEvent;
                String year;
                String tmpTable;
                String sqlcmd;

                for (int i = 0; i < list.Count; i++) {
                    myEvent = ((MyEvent)list[i]);
                    year = myEvent.getStartTime().ToString("yyyy");
                    tmpTable = "event" + year;

                    sqlcmd = "delete from " + tmpTable + " where eventId = '" + myEvent.getEventId() + "' and owner = '" + myEvent.getOwner() + "'";
                    
                    SqlCommand cmd = new SqlCommand(sqlcmd, conn);

                    cmd.ExecuteNonQuery();
                }
                conn.Close();

            }
            catch (Exception ex)
            {
                Debug.WriteLine("dal deleteEvent 出错:");
                Debug.WriteLine(ex.Message);
            }
        }


        /// <summary>修改一个备忘录事件
        /// </summary>
        /// <param name="myEvent">要修改的备忘录事件</param>
        public void changeEvent(MyEvent myEvent, String newOwner) {
            Debug.WriteLine(" DAL note1: " + myEvent.getEventNote());

            deleteEvent(myEvent);//根据事件原来的id和owner,找到它,把它删除
            //根据开始时间创建新的id
            String newEventId = DateTime.Now.ToString("yyyyMMddHHmmss");
            
            myEvent.setEventId(newEventId);
            myEvent.setOwner(newOwner);//传进来新的owner,赋值给此事件
            List<MyEvent> list = new List<MyEvent>();
            list.Add(myEvent);
            Debug.WriteLine(" DAL note2: " + myEvent.getEventNote());
            addEvent(list);
        }
    }

}

5.7 MemoBLL

MemoBLL.cs

using MemoModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MemoBLL
{
    public class MemoBLL
    {
        private MemoDAL.MemoDAL dal;

        public MemoBLL() {
            dal = new MemoDAL.MemoDAL();
        }

        /// <summary>传入时间,再调用DAL的相关函数,用来得到这一天的备忘录
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <returns></returns>
        public List<MyEvent> getEvent(DateTime dateTime)
        {

            return dal.getEvent(dateTime);
        }

        
        /// <summary>传入年份,调用DAL的相关函数,用来得到这一年的备忘录
        /// </summary>
        /// <param name="year">年份</param>
        /// <returns></returns>
        public List<MyEvent> getEvent(String year)
        {
            return dal.getEvent(year);
        }

        #region 被弃用的addEvent方法
        / <summary>传入事件,再调用DAL的相关函数,用来增加备忘录。
        / </summary>
        / <param name="myEvent">事件</param>
        //public void addEvent(MyEvent myEvent)
        //{
        //    dal.addEvent(myEvent);
        //}
        #endregion

        /// <summary>传入事件,再调用DAL的相关函数,用来增加备忘录。
        /// </summary>
        /// <param name="list">要保存的备忘录事件列表</param>
        public void addEvent(List<MyEvent> list)
        {
            dal.addEvent(list);
        }

        
        /// <summary>传入事件,再调用DAL的相关函数,用来修改备忘录。
        /// </summary>
        /// <param name="myEvent">事件</param>
        public void changeEvent(MyEvent myEvent, String newOwner)
        {
            dal.changeEvent(myEvent, newOwner);
        }
        
        /// <summary>传入事件,再调用DAL的相关函数,用来删除某条备忘录。
        /// </summary>
        /// <param name="myEvent">事件</param>
        public void deletEvent(MyEvent myEvent)
        {
            dal.deleteEvent(myEvent);
        }

        /// <summary>传入事件列表,再调用DAL的相关函数,用来删除这些备忘录。
        /// </summary>
        /// <param name="list">要删除的事件列表</param>
        public void deletEvent(List<MyEvent> list)
        {
            dal.deleteEvent(list);
        }
    }
}

 

  • 5
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值