private void Select(DateTimeInfo info)
 {
     _fireSelectionChangedEvent = false;
     TextBox.Select(info.StartPosition, info.Length);
     _fireSelectionChangedEvent = true;
     _selectedDateTimeInfo      = info;
 }
        private void UpdateDateTime(int value)
        {
            _fireSelectionChangedEvent = false;
            DateTimeInfo info = _selectedDateTimeInfo;

            //this only occurs when the user manually type in a value for the Value Property
            if (info == null)
            {
                info = _dateTimeInfoList[0];
            }

            switch (info.Type)
            {
            case DateTimePart.Year:
            {
                Value = ((DateTime)Value).AddYears(value);
                break;
            }

            case DateTimePart.Month:
            case DateTimePart.MonthName:
            {
                Value = ((DateTime)Value).AddMonths(value);
                break;
            }

            case DateTimePart.Day:
            case DateTimePart.DayName:
            {
                Value = ((DateTime)Value).AddDays(value);
                break;
            }

            case DateTimePart.Hour12:
            case DateTimePart.Hour24:
            {
                Value = ((DateTime)Value).AddHours(value);
                break;
            }

            case DateTimePart.Minute:
            {
                Value = ((DateTime)Value).AddMinutes(value);
                break;
            }

            case DateTimePart.Second:
            {
                Value = ((DateTime)Value).AddSeconds(value);
                break;
            }

            case DateTimePart.Millisecond:
            {
                Value = ((DateTime)Value).AddMilliseconds(value);
                break;
            }

            case DateTimePart.AmPmDesignator:
            {
                Value = ((DateTime)Value).AddHours(value * 12);
                break;
            }

            default:
            {
                break;
            }
            }

            //we loose our selection when the Value is set so we need to reselect it without firing the selection changed event
            TextBox.Select(info.StartPosition, info.Length);
            _fireSelectionChangedEvent = true;
        }
        private void InitializeDateTimeInfoList()
        {
            _dateTimeInfoList.Clear();

            string format = GetFormatString(Format);

            if (format == null)
            {
                return;
            }

            while (format.Length > 0)
            {
                int          elementLength = GetElementLengthByFormat(format);
                DateTimeInfo info          = null;

                switch (format[0])
                {
                case '"':
                case '\'':
                {
                    int closingQuotePosition = format.IndexOf(format[0], 1);
                    info = new DateTimeInfo {
                        IsReadOnly = true, Type = DateTimePart.Other, Length = 1, Content = format.Substring(1, Math.Max(1, closingQuotePosition - 1))
                    };
                    elementLength = Math.Max(1, closingQuotePosition + 1);
                    break;
                }

                case 'D':
                case 'd':
                {
                    string d = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        d = "%" + d;
                    }

                    if (elementLength > 2)
                    {
                        info = new DateTimeInfo {
                            IsReadOnly = true, Type = DateTimePart.DayName, Format = d
                        }
                    }
                    ;
                    else
                    {
                        info = new DateTimeInfo {
                            IsReadOnly = false, Type = DateTimePart.Day, Format = d
                        }
                    };
                    break;
                }

                case 'F':
                case 'f':
                {
                    string f = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        f = "%" + f;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = false, Type = DateTimePart.Millisecond, Format = f
                    };
                    break;
                }

                case 'h':
                {
                    string h = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        h = "%" + h;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = false, Type = DateTimePart.Hour12, Format = h
                    };
                    break;
                }

                case 'H':
                {
                    string H = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        H = "%" + H;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = false, Type = DateTimePart.Hour24, Format = H
                    };
                    break;
                }

                case 'M':
                {
                    string M = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        M = "%" + M;
                    }

                    if (elementLength >= 3)
                    {
                        info = new DateTimeInfo {
                            IsReadOnly = false, Type = DateTimePart.MonthName, Format = M
                        }
                    }
                    ;
                    else
                    {
                        info = new DateTimeInfo {
                            IsReadOnly = false, Type = DateTimePart.Month, Format = M
                        }
                    };
                    break;
                }

                case 'S':
                case 's':
                {
                    string s = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        s = "%" + s;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = false, Type = DateTimePart.Second, Format = s
                    };
                    break;
                }

                case 'T':
                case 't':
                {
                    string t = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        t = "%" + t;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = false, Type = DateTimePart.AmPmDesignator, Format = t
                    };
                    break;
                }

                case 'Y':
                case 'y':
                {
                    string y = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        y = "%" + y;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = false, Type = DateTimePart.Year, Format = y
                    };
                    break;
                }

                case '\\':
                {
                    if (format.Length >= 2)
                    {
                        info = new DateTimeInfo {
                            IsReadOnly = true, Content = format.Substring(1, 1), Length = 1, Type = DateTimePart.Other
                        };
                        elementLength = 2;
                    }
                    break;
                }

                case 'g':
                {
                    string g = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        g = "%" + g;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = true, Type = DateTimePart.Period, Format = format.Substring(0, elementLength)
                    };
                    break;
                }

                case 'm':
                {
                    string m = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        m = "%" + m;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = false, Type = DateTimePart.Minute, Format = m
                    };
                    break;
                }

                case 'z':
                {
                    string z = format.Substring(0, elementLength);
                    if (elementLength == 1)
                    {
                        z = "%" + z;
                    }

                    info = new DateTimeInfo {
                        IsReadOnly = true, Type = DateTimePart.TimeZone, Format = z
                    };
                    break;
                }

                default:
                {
                    elementLength = 1;
                    info          = new DateTimeInfo {
                        IsReadOnly = true, Length = 1, Content = format[0].ToString(), Type = DateTimePart.Other
                    };
                    break;
                }
                }

                _dateTimeInfoList.Add(info);
                format = format.Substring(elementLength);
            }
        }
        private void UpdateDateTime(int value)
        {
            _fireSelectionChangedEvent = false;
            DateTimeInfo info = _selectedDateTimeInfo;

            //this only occurs when the user manually type in a value for the Value Property
            if (info == null)
            {
                info = _dateTimeInfoList[0];
            }

            try
            {
                switch (info.Type)
                {
                case DateTimePart.Year:
                {
                    Value = ((DateTime)Value).AddYears(value);
                    break;
                }

                case DateTimePart.Month:
                case DateTimePart.MonthName:
                {
                    Value = ((DateTime)Value).AddMonths(value);
                    break;
                }

                case DateTimePart.Day:
                case DateTimePart.DayName:
                {
                    Value = ((DateTime)Value).AddDays(value);
                    break;
                }

                case DateTimePart.Hour12:
                case DateTimePart.Hour24:
                {
                    Value = ((DateTime)Value).AddHours(value);
                    break;
                }

                case DateTimePart.Minute:
                {
                    Value = ((DateTime)Value).AddMinutes(value);
                    break;
                }

                case DateTimePart.Second:
                {
                    Value = ((DateTime)Value).AddSeconds(value);
                    break;
                }

                case DateTimePart.Millisecond:
                {
                    Value = ((DateTime)Value).AddMilliseconds(value);
                    break;
                }

                case DateTimePart.AmPmDesignator:
                {
                    Value = ((DateTime)Value).AddHours(value * 12);
                    break;
                }

                default:
                {
                    break;
                }
                }
            }
            catch
            {
                //this can occur if the date/time = 1/1/0001 12:00:00 AM which is the smallest date allowed.
                //I could write code that would validate the date each and everytime but I think that it would be more
                //efficient if I just handle the edge case and allow an exeption to occur and swallow it instead.
            }

            //we loose our selection when the Value is set so we need to reselect it without firing the selection changed event
            TextBox.Select(info.StartPosition, info.Length);
            _fireSelectionChangedEvent = true;
        }