winform自定义日期控件,要求可以手动输入日期DatePicker

要求:文本框中能手动输入数字,向上箭头根据鼠标位置给年月日递增,向下箭头递减

一:页面加载时:

private void FlatDatePicker_Load(object sender, EventArgs e)
{
    txtMain.Text = DateTime.Now.ToString("MM/dd/yyyy");
    txtMain.Location = new Point(10,19);
    txtMain.Width = 150;
    btnUp.Width = 20;
    btnUp.Height = txtMain.Height / 2;
    btnDown.Width = 20;
    btnDown.Height = txtMain.Height / 2;
    this.Width = txtMain.Width + 20;
    this.Height = txtMain.Height;
    btnUp.Location = new Point(txtMain.Width, 0);
    btnDown.Location = new Point(txtMain.Width, btnUp.Height);
}

二、按下Delete键时不允许删除"/"

private void txtMain_KeyDown(object sender, KeyEventArgs e)
{
    switch (e.KeyCode)
    {
        //不允许Delete键删除'/'
        case Keys.Delete:
            int selectIndex = txtMain.SelectionStart;
            int selectLength = txtMain.SelectionLength;
            int xiegangIndex1 = txtMain.Text.IndexOf('/');
            int xiegangIndex2 = txtMain.Text.LastIndexOf('/');
            bool condition1 = selectLength == 0 && (selectIndex == xiegangIndex1 || selectIndex == xiegangIndex2);
            bool condition2 = selectLength > 0 && txtMain.Text.Substring(selectIndex, selectLength).Contains("/");
            if (condition1 || condition2)
            {
                e.Handled = true;
            }
            break;
        default:
            break;
    }
}

三、按下键时排除不合适字符

private void txtMain_KeyPress(object sender, KeyPressEventArgs e)
{
    #region 不合适字符
    if (!Char.IsNumber(e.KeyChar) && !Char.IsPunctuation(e.KeyChar) && !Char.IsControl(e.KeyChar))
    {
        e.Handled = true;//消除不合适字符  
    }
    else if (Char.IsPunctuation(e.KeyChar))
    {
        if (e.KeyChar != '.' || this.Text.Length == 0)//小数点  
        {
            e.Handled = true;
        }
        if (this.Text.LastIndexOf('.') != -1)
        {
            e.Handled = true;
        }
    }
    else if (txtMain.Text == "")
    {
        e.Handled = true;
    }
    #endregion
    #region 按下数字键 数字超过指定的年月日则无效
    if (Char.IsNumber(e.KeyChar))//按下数字键
    {
        int selectedIndex = txtMain.SelectionStart;
        int selectedLength = txtMain.SelectionLength;
        int monthLength = txtMain.Text.Split('/')[0].Length;
        int dayLength = txtMain.Text.Split('/')[1].Length;
        int yearLength = txtMain.Text.Split('/')[2].Length;
        int monthIndex = txtMain.Text.IndexOf('/', 0, 3);
        int dayIndex = txtMain.Text.IndexOf('/', 3);

        int month = DateTime.Now.Month;
        int day = DateTime.Now.Day;
        int year = DateTime.Now.Year;
        if (txtMain.SelectedText.Contains("/"))
        {
            e.Handled = true;
        }
        else if (selectedIndex <= monthIndex)
        {//修改月份
            #region 修改月份
            if (selectedIndex == 0)
            {
                if (selectedLength == 0)
                {
                    if (monthLength == 1)
                    {
                        int.TryParse(e.KeyChar.ToString() + txtMain.Text.Substring(0, 1), out month);
                    }
                    else if (monthLength == 2)
                    {
                        e.Handled = true;
                    }
                }
                else if (selectedLength == 1)
                {
                    if (monthLength == 1)
                    {
                        int.TryParse(e.KeyChar.ToString(), out month);
                    }
                    else if (monthLength == 2)
                    {
                        int.TryParse(e.KeyChar.ToString() + txtMain.Text.Substring(1, 1), out month);
                    }
                }
                else if (selectedLength == 2)
                {
                    int.TryParse(e.KeyChar.ToString(), out month);
                }
            }
            else if (selectedIndex == 1)
            {
                if (selectedLength == 0)
                {
                    if (monthLength == 1)
                    {
                        int.TryParse(txtMain.Text.Substring(0, 1) + e.KeyChar.ToString(), out month);
                    }
                    else if (monthLength == 2)
                    {
                        e.Handled = true;
                    }
                }
                else if (selectedLength == 1)
                {
                    int.TryParse(txtMain.Text.Substring(0, 1) + e.KeyChar.ToString(), out month);
                }
            }
            else if (selectedIndex == 2)
            {
                e.Handled = true;
            }

            if (month <= 0 || month >= 13)
            {
                e.Handled = true;
            }
            #endregion
        }
        else if (selectedIndex <= dayIndex)
        {//修改日期
            #region 修改日期
            if (selectedIndex == 3)
            {
                if (selectedLength == 0)
                {
                    if (dayLength == 1)
                    {
                        int.TryParse(e.KeyChar.ToString() + txtMain.Text.Substring(3, 1), out day);
                    }
                    else if (dayLength == 2)
                    {
                        e.Handled = true;
                    }
                }
                else if (selectedLength == 1)
                {
                    if (dayLength == 1)
                    {
                        int.TryParse(e.KeyChar.ToString(), out day);
                    }
                    else if (dayLength == 2)
                    {
                        int.TryParse(e.KeyChar.ToString() + txtMain.Text.Substring(4, 1), out day);
                    }
                }
                else if (selectedLength == 2)
                {
                    int.TryParse(e.KeyChar.ToString(), out day);
                }
            }
            else if (selectedIndex == 4)
            {
                if (selectedLength == 0)
                {
                    if (dayLength == 1)
                    {
                        int.TryParse(txtMain.Text.Substring(3, 1) + e.KeyChar.ToString(), out day);
                    }
                    else if (dayLength == 2)
                    {
                        e.Handled = true;
                    }
                }
                else if (selectedLength == 1)
                {
                    int.TryParse(txtMain.Text.Substring(3, 1) + e.KeyChar.ToString(), out day);
                }
            }
            else if (selectedIndex == 5)
            {
                e.Handled = true;
            }

            int.TryParse(txtMain.Text.Split('/')[0], out month);
            int.TryParse(txtMain.Text.Split('/')[2], out year);
            if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day > 31)
            {
                e.Handled = true;
            }
            else if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30)
            {
                e.Handled = true;
            }
            if (DateTime.IsLeapYear(year) && month == 2 && day > 29)
            {
                e.Handled = true;
            }
            else if (!DateTime.IsLeapYear(year) && month == 2 && day > 28)
            {
                e.Handled = true;
            }
            #endregion
        }
        else
        {//修改年份
            #region 修改年份
            if (yearLength == 3)
            {
                int.TryParse(txtMain.Text.Substring(6, 3) + e.KeyChar.ToString(), out year);
                if (year < 1900)
                {
                    e.Handled = true;
                    //txtMain.Text = txtMain.Text.Split('/')[0] + "/" + txtMain.Text.Split('/')[1] + "/" + DateTime.Now.Year;
                }
            }
            else if (yearLength > 3 && selectedLength <= 0)
            {
                e.Handled = true;
            }
            #endregion
        }
    }
    #endregion
    #region 按下BackSpcae键 不允许删除"/"
    if (e.KeyChar == '')
    {
        int selectIndex = txtMain.SelectionStart;
        int selectlength = txtMain.SelectionLength;
        if (selectlength == 0 && selectIndex > 0)
        {
            string delStr = txtMain.Text.Substring(selectIndex - 1, 1);
            if (delStr == "/")
            {
                e.Handled = true;
            }
        }
        if (selectlength > 0)
        {
            string delStr = txtMain.Text.Substring(selectIndex, selectlength);
            if (delStr.Contains("/"))
            {
                e.Handled = true;
            }
        }
    }
    #endregion
}

四、

private void txtMain_KeyUp(object sender, KeyEventArgs e)
{
    int selectIndex = txtMain.SelectionStart;
    int month = 0;
    int.TryParse(txtMain.Text.Split('/')[0], out month);
    int day = 0;
    int.TryParse(txtMain.Text.Split('/')[1], out day);
    int year = 0;
    int.TryParse(txtMain.Text.Split('/')[2], out year);
    int xiegangIndex1 = txtMain.Text.IndexOf('/');//第一个'/'的位置
    int xiegangIndex2 = txtMain.Text.LastIndexOf('/');//第二个'/'的位置
    switch (e.KeyCode)
    {
        #region 松开左右键
        case Keys.Left:
            if (selectIndex <= xiegangIndex1)
            {
                FillDay();
                Fillyear();
            }
            else if (selectIndex <= xiegangIndex2)
            {
                FillMonth();
                Fillyear();
            }
            else
            {
                FillMonth();
                FillDay();
            }
            txtMain.SelectionStart = selectIndex;
            break;
        case Keys.Right:
            if (selectIndex <= xiegangIndex1)
            {
                FillDay();
                Fillyear();
            }
            else if (selectIndex <= xiegangIndex2)
            {
                FillMonth();
                Fillyear();
            }
            else
            {
                FillMonth();
                FillDay();
            }
            break;
        #endregion
        case Keys.End:
            break;
        case Keys.Home:
            break;
        #region 上下键增减年月日
        case Keys.Up:
            selectIndex++;
            if (selectIndex < 3)
            {
                if (month < 12)
                {
                    month++;
                    FillMonth(month);
                }
                txtMain.Select(0, 2);
            }
            else if (selectIndex < 6)
            {
                bool condition1 = (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day < 31;
                bool condition2 = (month == 4 || month == 6 || month == 9 || month == 11) && day < 30;
                bool condition3 = month == 2 && (DateTime.IsLeapYear(year) && day < 29 || !DateTime.IsLeapYear(year) && day < 28);
                if (condition1 || condition2 || condition3)
                {
                    day++;
                    FillDay(day);
                }
                txtMain.Select(3, 2);
            }
            else
            {
                if (year < 9999)
                {
                    year++;
                    Fillyear(year);
                }
                txtMain.Select(6, 4);
            }
            break;
        case Keys.Down:
            selectIndex--;
            if (selectIndex < 3)
            {
                if (month > 1)
                {
                    month--;
                    FillMonth(month);
                }
                txtMain.SelectionStart = 0;
                txtMain.Select(0, 2);
            }
            else if (selectIndex < 6)
            {
                if (day > 1)
                {
                    day--;
                    FillDay(day);
                }
                txtMain.SelectionStart = 3;
                txtMain.Select(3, 2);
            }
            else
            {
                if (year > 1900)
                {
                    year--;
                    Fillyear(year);
                }
                txtMain.SelectionStart = 6;
                txtMain.Select(6, 4);
            }
            break;
        #endregion
        case Keys.Delete:
            break;
        #region 松开数字键
        case Keys.D0:
        case Keys.D1:
        case Keys.D2:
        case Keys.D3:
        case Keys.D4:
        case Keys.D5:
        case Keys.D6:
        case Keys.D7:
        case Keys.D8:
        case Keys.D9:
        case Keys.NumPad0:
        case Keys.NumPad1:
        case Keys.NumPad2:
        case Keys.NumPad3:
        case Keys.NumPad4:
        case Keys.NumPad5:
        case Keys.NumPad6:
        case Keys.NumPad7:
        case Keys.NumPad8:
        case Keys.NumPad9:
            if ((month > 1 || selectIndex > 1) && txtMain.Text.Split('/')[0].Length < 2 || (selectIndex == 2 && txtMain.Text.Split('/')[1].Length == 2))
            {
                EidtDay(month);
                FillMonth();
                txtMain.Select(3, 2);
            }

            if ((month == 2 && day > 2 || month != 2 && day > 3 || (selectIndex < 3 || selectIndex > 4)) && txtMain.Text.Split('/')[1].Length < 2 || (selectIndex == 5 && txtMain.Text.Split('/')[1].Length == 2))
            {
                FillDay();
                txtMain.Select(6, 4);
            }

            if (selectIndex > 6 && txtMain.Text.Split('/')[2].Length >= 4)
            {
                EidtDay(month, year);
                Fillyear();
            }
            break;
        #endregion
        default:
            break;
    }
}

五、

private void txtMain_Leave(object sender, EventArgs e)
{
    FillMonth();
    FillDay();
    Fillyear();
}

六、

private void txtMain_MouseDown(object sender, MouseEventArgs e)
{
    FillMonth();
    FillDay();
    Fillyear();
}

七、

private void btnUp_Click(object sender, EventArgs e)
{
    int selectIndex = txtMain.SelectionStart;
    int month = 0;
    int.TryParse(txtMain.Text.Split('/')[0], out month);
    int day = 0;
    int.TryParse(txtMain.Text.Split('/')[1], out day);
    int year = 0;
    int.TryParse(txtMain.Text.Split('/')[2], out year);
    if (selectIndex < 3)
    {
        if (month < 12)
        {
            month++;
            FillMonth(month);
        }
        txtMain.Select();
        txtMain.Select(0, 2);
    }
    else if (3 <= selectIndex && selectIndex < 6)
    {
        bool condition1 = (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day < 31;
        bool condition2 = (month == 4 || month == 6 || month == 9 || month == 11) && day < 30;
        bool condition3 = month == 2 && (DateTime.IsLeapYear(year) && day < 29 || !DateTime.IsLeapYear(year) && day < 28);
        if (condition1 || condition2 || condition3)
        {
            day++;
            FillDay(day);
        }
        txtMain.Select();
        txtMain.Select(3, 2);
    }
    else if (selectIndex >= 6)
    {
        if (year < 9999)
        {
            year++;
            Fillyear(year);
        }
        txtMain.Select();
        txtMain.Select(6, 4);
    }
}
private void btnDown_Click(object sender, EventArgs e)
{
    int selectIndex = txtMain.SelectionStart;
    int month = 0;
    int.TryParse(txtMain.Text.Split('/')[0], out month);
    int day = 0;
    int.TryParse(txtMain.Text.Split('/')[1], out day);
    int year = 0;
    int.TryParse(txtMain.Text.Split('/')[2], out year);
    if (selectIndex < 3)
    {
        if (month > 1)
        {
            month--;
            FillMonth(month);
        }
        txtMain.Select();
        txtMain.Select(0, 2);
    }
    else if (3 <= selectIndex && selectIndex < 6)
    {
        if (day > 1)
        {
            day--;
            FillDay(day);
        }
        txtMain.Select();
        txtMain.Select(3, 2);
    }
    else if (selectIndex >= 6)
    {
        if (year > 1900)
        {
            year--;
            Fillyear(year);
        }
        txtMain.Select();
        txtMain.Select(6, 4);
    }
}

八、

private bool Fillyear(int year = 0)
{
    bool editBool = false;
    if (year == 0)
    {
        int.TryParse(txtMain.Text.Split('/')[2], out year);
        if (year == 0)
        {
            year = DateTime.Now.Year;
            editBool = true;
        }
    }
    if (year < 1900 && year > 0)
    {
        txtMain.Text = txtMain.Text.Split('/')[0] + "/" + txtMain.Text.Split('/')[1] + "/" + DateTime.Now.Year;
        editBool = true;
    }
    else
    {
        txtMain.Text = txtMain.Text.Split('/')[0] + "/" + txtMain.Text.Split('/')[1] + "/" + year;
        editBool = true;
    }
    return editBool;
    //txtMain.Select(0, 2);
}

private bool FillMonth(int month = 0)
{
    bool editBool = false;
    if (month == 0)
    {
        int.TryParse(txtMain.Text.Split('/')[0], out month);//txtMain.Text.Substring(0, 2) 
        if (month == 0)
        {
            month = DateTime.Now.Month;
            editBool = true;
        }
    }
    if (9 >= month && month > 0)
    {
        txtMain.Text = "0" + month.ToString() + "/" + txtMain.Text.Split('/')[1] + "/" + txtMain.Text.Split('/')[2];
        editBool = true;
    }
    else
    {
        txtMain.Text = month + "/" + txtMain.Text.Split('/')[1] + "/" + txtMain.Text.Split('/')[2];
        editBool = true;
    }
    return editBool;
    //txtMain.Select(3, 2);
}

private bool FillDay(int day = 0)
{
    bool editBool = false;
    if (day == 0)
    {
        int.TryParse(txtMain.Text.Split('/')[1], out day);//txtMain.Text.Substring(0, 2)  
        if (day == 0)
        {
            day = DateTime.Now.Day;
            editBool = true;
        }
    }
    if (9 >= day && day > 0)
    {
        txtMain.Text = txtMain.Text.Split('/')[0] + "/" + "0" + day.ToString() + "/" + txtMain.Text.Split('/')[2];
        editBool = true;
    }
    else
    {
        txtMain.Text = txtMain.Text.Split('/')[0] + "/" + day.ToString() + "/" + txtMain.Text.Split('/')[2];
        editBool = true;
    }
    return editBool;
    //txtMain.Select(6, 4);
}

九、

/// <summary>
/// 根据年月判断日期是否超出范围 是则修改
/// </summary>
private void EidtDay(int month = 0, int year = 0)
{
    if (month == 0)
    {
        int.TryParse(txtMain.Text.Split('/')[0], out month);
    }
    int day = 0;
    int.TryParse(txtMain.Text.Split('/')[1], out day);
    if (year == 0)
    {
        int.TryParse(txtMain.Text.Split('/')[2], out year);
    }
    if (month == 0)
    {
        month = DateTime.Now.Month;
    }
    if (day == 0)
    {
        day = DateTime.Now.Day;
    }
    if (year == 0)
    {
        year = DateTime.Now.Year;
    }
    if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30)
    {
        if (month < 11)
        {
            txtMain.Text = "0" + month + "/30/" + year;
        }
     else
     {
        txtMain.Text = month + "/30/" + year;
     }
}
   if (DateTime.IsLeapYear(year) && month == 2 && day > 29)
    {
        txtMain.Text = "0" + month + "/29/" + year;
    }
    if (!DateTime.IsLeapYear(year) && month == 2 && day > 28)
    {
        txtMain.Text = "0" + month + "/28/" + year;
    }
}
原文地址:https://www.cnblogs.com/zhyue93/p/DatePicker.html