| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731 |
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- // Copyright (c) 2004 Novell, Inc.
- //
- // Authors:
- // John BouAntoun [email protected]
- //
- // TODO:
- // - implement custom formatting of the date time value
- // - implement any behaviour associate with UseUpDown (painting, key and mouse)
- // - implement key processing and responding
- // - fix MonthCalendar Popdown on form move
- // - wire in all events from monthcalendar
- using System;
- using System.Drawing;
- using System.Collections;
- using System.ComponentModel;
- using System.Windows.Forms;
- namespace System.Windows.Forms {
- [DefaultEvent("ValueChanged")]
- [DefaultProperty("Value")]
- [Designer("System.Windows.Forms.Design.DateTimePickerDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
- public class DateTimePicker : Control {
- #region Public variables
-
- // this class has to have the specified hour, minute and second, as it says in msdn
- public static readonly DateTime MaxDateTime = new DateTime (9998, 12, 31, 23, 59, 59);
- public static readonly DateTime MinDateTime = new DateTime (1753, 1, 1);
-
- #endregion // Public variables
-
- #region Local variables
-
- protected static readonly Color DefaultMonthBackColor = ThemeEngine.Current.ColorWindow;
- protected static readonly Color DefaultTitleBackColor = ThemeEngine.Current.ColorActiveCaption;
- protected static readonly Color DefaultTitleForeColor = ThemeEngine.Current.ColorActiveCaptionText;
- protected static readonly Color DefaultTrailingForeColor = Color.Gray;
-
- internal MonthCalendar month_calendar;
- bool is_checked;
- string custom_format;
- LeftRightAlignment drop_down_align;
- DateTimePickerFormat format;
- DateTime max_date;
- DateTime min_date;
- bool show_check_box;
- bool show_up_down;
- string text;
- DateTime date_value;
-
- // variables used for drawing and such
- internal int up_down_width;
- internal bool is_drop_down_visible;
-
- #endregion // Local variables
-
- #region public constructors
-
- // only public constructor
- public DateTimePicker () {
-
- // initialise the month calendar
- month_calendar = new MonthCalendar (this);
- month_calendar.CalendarDimensions = new Size (1, 1);
- month_calendar.MaxSelectionCount = 1;
- month_calendar.ForeColor = Control.DefaultForeColor;
- month_calendar.BackColor = DefaultMonthBackColor;
- month_calendar.TitleBackColor = DefaultTitleBackColor;
- month_calendar.TitleForeColor = DefaultTitleForeColor;
- month_calendar.TrailingForeColor = DefaultTrailingForeColor;
- month_calendar.Visible = false;
-
- // initialise other variables
- is_checked = false;
- custom_format = string.Empty;
- drop_down_align = LeftRightAlignment.Left;
- format = DateTimePickerFormat.Long;
- max_date = MaxDateTime;
- min_date = MinDateTime;
- show_check_box = false;
- show_up_down = false;
- date_value = DateTime.Now;
- text = FormatValue ();
-
- up_down_width = 10;
- is_drop_down_visible = false;
-
- month_calendar.DateSelected += new DateRangeEventHandler (MonthCalendarDateSelectedHandler);
- KeyPress += new KeyPressEventHandler (KeyPressHandler);
- // LostFocus += new EventHandler (LostFocusHandler);
- MouseDown += new MouseEventHandler (MouseDownHandler);
- Paint += new PaintEventHandler (PaintHandler);
-
- SetStyle (ControlStyles.UserPaint | ControlStyles.StandardClick, false);
- SetStyle (ControlStyles.FixedHeight, true);
- }
-
- #endregion
-
- #region public properties
-
- // no reason why this is overridden
- [Browsable(false)]
- [EditorBrowsable(EditorBrowsableState.Never)]
- public Color BackColor {
- set {
- base.BackColor = value;
- }
- get {
- return base.BackColor;
- }
- }
-
- // no reason why this is overridden
- [Browsable(false)]
- [EditorBrowsable(EditorBrowsableState.Never)]
- public override Image BackgroundImage {
- set {
- base.BackgroundImage = value;
- }
- get {
- return base.BackgroundImage;
- }
- }
- [AmbientValue(null)]
- [Localizable(true)]
- public Font CalendarFont {
- set {
- month_calendar.Font = value;
- }
- get {
- return month_calendar.Font;
- }
- }
- public Color CalendarForeColor {
- set {
- month_calendar.ForeColor = value;
- }
- get {
- return month_calendar.ForeColor;
- }
- }
- public Color CalendarMonthBackground {
- set {
- month_calendar.BackColor = value;
- }
- get {
- return month_calendar.BackColor;
- }
- }
- public Color CalendarTitleBackColor {
- set {
- month_calendar.TitleBackColor = value;
- }
- get {
- return month_calendar.TitleBackColor;
- }
- }
- public Color CalendarTitleForeColor {
- set {
- month_calendar.TitleForeColor = value;
- }
- get {
- return month_calendar.TitleForeColor;
- }
- }
- public Color CalendarTrailingForeColor {
- set {
- month_calendar.TrailingForeColor = value;
- }
- get {
- return month_calendar.TrailingForeColor;
- }
- }
-
- // when checked the value is grayed out
- [Bindable(true)]
- [DefaultValue(true)]
- public bool Checked {
- set {
- if (is_checked != value) {
- is_checked = value;
- // invalidate the value inside this control
- this.Invalidate (date_area_rect);
- }
- }
- get {
- return is_checked;
- }
- }
-
- // the custom format string to format this control with
- [DefaultValue(null)]
- [RefreshProperties(RefreshProperties.Repaint)]
- public string CustomFormat {
- set {
- if (custom_format != value) {
- custom_format = value;
- if (this.Format == DateTimePickerFormat.Custom) {
- // TODO: change the text value of the dtp
- }
- }
- }
- get {
- return custom_format;
- }
- }
-
- // which side the drop down is to be aligned on
- [DefaultValue(LeftRightAlignment.Left)]
- [Localizable(true)]
- public LeftRightAlignment DropDownAlign {
- set {
- if (drop_down_align != value) {
- drop_down_align = value;
- }
- }
- get {
- return drop_down_align;
- }
- }
- [Browsable(false)]
- [EditorBrowsable(EditorBrowsableState.Never)]
- public override Color ForeColor {
- set {
- base.ForeColor = value;
- }
- get {
- return base.ForeColor;
- }
- }
-
- // the format of the date time picker text, default is long
- [RefreshProperties(RefreshProperties.Repaint)]
- public DateTimePickerFormat Format {
- set {
- if (format != value) {
- format = value;
- this.OnFormatChanged (EventArgs.Empty);
- // invalidate the value inside this control
- this.Invalidate (date_area_rect);
- }
- }
- get {
- return format;
- }
- }
-
- public DateTime MaxDate {
- set {
- if (value < min_date) {
- throw new ArgumentException ();
- }
- if (value > MaxDateTime) {
- throw new SystemException ();
- }
- if (max_date != value) {
- max_date = value;
-
- // TODO: verify this is correct behaviour when value > max date
- if (Value > max_date) {
- Value = max_date;
- // invalidate the value inside this control
- this.Invalidate (date_area_rect);
- }
- }
- }
- get {
- return max_date;
- }
- }
-
- public DateTime MinDate {
- set {
- if (value < min_date) {
- throw new ArgumentException ();
- }
- if (value < MinDateTime) {
- throw new SystemException ();
- }
- if (min_date != value) {
- min_date = value;
-
- // TODO: verify this is correct behaviour when value > max date
- if (Value < min_date) {
- Value = min_date;
- // invalidate the value inside this control
- this.Invalidate (date_area_rect);
- }
- }
- }
- get {
- return min_date;
- }
- }
-
- // the prefered height to draw this control using current font
- [Browsable(false)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int PreferredHeight {
- get {
- return this.Font.Height + 7;
- }
- }
-
- // whether or not the check box is shown
- [DefaultValue(false)]
- public bool ShowCheckBox {
- set {
- if (show_check_box != value) {
- show_check_box = value;
- // invalidate the value inside this control
- this.Invalidate (date_area_rect);
- }
- }
- get {
- return show_check_box;
- }
- }
-
- // if true show the updown control, else popup the monthcalendar
- [DefaultValue(false)]
- public bool ShowUpDown {
- set {
- if (show_up_down != value) {
- show_up_down = value;
- // need to invalidate the whole control
- this.Invalidate ();
- }
- }
- get {
- return show_up_down;
- }
- }
- [Browsable(false)]
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public string Text {
- set {
- // TODO: if the format is a custom format we need to do a custom parse here
- DateTime parsed_value = DateTime.Parse (value);
- if (date_value != parsed_value) {
- Value = parsed_value;
- }
- text = FormatValue ();
- }
- get {
- return text;
- }
- }
- [Bindable(true)]
- [RefreshProperties(RefreshProperties.All)]
- public DateTime Value {
- set {
- if (date_value != value) {
- date_value = value;
- text = FormatValue ();
- this.OnValueChanged (EventArgs.Empty);
- this.Invalidate (date_area_rect);
- }
- }
- get {
- return date_value;
- }
- }
- #endregion // public properties
-
- #region public methods
-
- // just return the text value
- public override string ToString () {
- return this.Text;
- }
-
- #endregion // public methods
-
- #region public events
-
- // raised when the monthcalendar is closed
- public event EventHandler CloseUp;
-
- // raised when the monthcalendar is opened
- public event EventHandler DropDown;
-
- // raised when the format of the value is changed
- public event EventHandler FormatChanged;
-
- // raised when the date Value is changed
- public event EventHandler ValueChanged;
-
- #endregion // public events
-
- #region protected properties
- // not sure why we're overriding this one
- protected override CreateParams CreateParams {
- get {
- return base.CreateParams;
- }
- }
-
- // specify the default size for this control
- protected override Size DefaultSize {
- get {
- // todo actually measure this properly
- return new Size (200, PreferredHeight);
- }
- }
-
- #endregion // protected properties
-
- #region protected methods
-
- // not sure why we're overriding this one
- protected override AccessibleObject CreateAccessibilityInstance () {
- return base.CreateAccessibilityInstance ();
- }
-
- // not sure why we're overriding this one
- protected override void CreateHandle () {
- base.CreateHandle ();
- }
-
- // not sure why we're overriding this one
- protected override void DestroyHandle () {
- base.DestroyHandle ();
- }
-
- // not sure why we're overriding this one
- protected override void Dispose (bool disposing) {
- base.Dispose (disposing);
- }
-
- // find out if this key is an input key for us, depends on which date part is focused
- protected override bool IsInputKey (Keys keyData) {
- // TODO: fix this implementation of IsInputKey
- return false;
- }
-
- // raises the CloseUp event
- protected virtual void OnCloseUp (EventArgs eventargs) {
- if (this.CloseUp != null) {
- this.CloseUp (this, eventargs);
- }
- }
-
- // raise the drop down event
- protected virtual void OnDropDown (EventArgs eventargs) {
- if (this.DropDown != null) {
- this.DropDown (this, eventargs);
- }
- }
-
- // raises the format changed event
- protected virtual void OnFormatChanged (EventArgs e) {
- if (this.FormatChanged != null) {
- this.FormatChanged (this, e);
- }
- }
-
- // not sure why we're overriding this one
- protected override void OnSystemColorsChanged (EventArgs e) {
- base.OnSystemColorsChanged (e);
- }
-
- // raise the ValueChanged event
- protected virtual void OnValueChanged (EventArgs eventargs) {
- if (this.ValueChanged != null) {
- this.ValueChanged (this, eventargs);
- }
- }
-
- // overridden to set the bounds of this control properly
- protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
- // TODO: ensure I implemented the bounds core setting properly.
- if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height ||
- (specified & BoundsSpecified.Size) == BoundsSpecified.Size) {
- base.SetBoundsCore (x, y, width, DefaultSize.Height, specified);
- } else {
- base.SetBoundsCore (x, y, width, height, specified);
- }
-
- // need to set the rectangles for all the support internal rects
- // this is done here as a optimisation since this is an array of rects
- if ((specified & BoundsSpecified.X) == BoundsSpecified.X ||
- (specified & BoundsSpecified.Y) == BoundsSpecified.Y) {
- // TODO set up all the datepart rects
- }
- }
- // not sure why we're overriding this
- protected override void WndProc (ref Message m) {
- base.WndProc (ref m);
- }
-
- #endregion // protected methods
-
- #region internal / private properties
-
- // this is the region that the date and the check box is drawn on
- internal Rectangle date_area_rect {
- get {
- Rectangle rect = this.ClientRectangle;
- if (ShowUpDown) {
- // set the space to the left of the up/down button
- if (rect.Width > (up_down_width + 4)) {
- rect.Width -= (up_down_width + 4);
- } else {
- rect.Width = 0;
- }
- } else {
- // set the space to the left of the up/down button
- // TODO make this use up down button
- if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 4)) {
- rect.Width -= SystemInformation.VerticalScrollBarWidth;
- } else {
- rect.Width = 0;
- }
- }
-
- rect.Inflate (-2, -2);
- return rect;
- }
- }
-
- // the rectangle for the drop down arrow
- internal Rectangle drop_down_arrow_rect {
- get {
- Rectangle rect = this.ClientRectangle;
- rect.X = rect.Right - SystemInformation.VerticalScrollBarWidth - 2;
- if (rect.Width > (SystemInformation.VerticalScrollBarWidth + 2)) {
- rect.Width = SystemInformation.VerticalScrollBarWidth;
- } else {
- rect.Width = Math.Max (rect.Width - 2, 0);
- }
-
- rect.Inflate (0, -2);
- return rect;
- }
- }
-
- // the part of the date that is currently hilighted
- internal Rectangle hilight_date_area {
- get {
- // TODO: put hilighted part calculation in here
- return Rectangle.Empty;
- }
- }
-
- #endregion
-
- #region internal / private methods
-
- [MonoTODO("Fix Dropdown location when System.Windows.Forms.Screen gets added")]
- private Point CalculateDropDownLocation (Rectangle parent_control_rect, Size child_size, bool align_left)
- {
- // default bottom left
- Point location = new Point(parent_control_rect.Left + 5, parent_control_rect.Bottom);
- // now adjust the alignment
- if (!align_left) {
- location.X = parent_control_rect.Right - child_size.Width;
- }
-
- Point screen_location = PointToScreen (location);
- // TODO: enable this part when screen comes into the classes
- /*
- Rectangle working_area = Screen.FromControl(this).WorkingArea;
- // now adjust if off the right side of the screen
- if (screen_location.X < working_area.X) {
- screen_location.X = working_area.X;
- }
- // now adjust if it should be displayed above control
- if (screen_location.Y + child_size.Height > working_area.Bottom) {
- screen_location.Y -= (parent_control_rect.Height + child_size.Height);
- }
- */
- return screen_location;
- }
-
- // actually draw this control
- internal void Draw (Rectangle clip_rect, Graphics dc)
- {
- ThemeEngine.Current.DrawDateTimePicker (dc, clip_rect, this);
- }
-
- // drop the calendar down
- internal void DropDownMonthCalendar ()
- {
- // ensure the right date is set for the month_calendar
- month_calendar.SetDate (this.date_value);
- // get a rectangle that has the dimensions of the text area,
- // but the height of the dtp control.
- Rectangle align_area = this.date_area_rect;
- align_area.Y = this.ClientRectangle.Y;
- align_area.Height = this.ClientRectangle.Height;
-
- // establish the month calendar's location
- month_calendar.Location = CalculateDropDownLocation (
- align_area,
- month_calendar.Size,
- (this.DropDownAlign == LeftRightAlignment.Left));
- month_calendar.Show ();
- month_calendar.Focus ();
- month_calendar.Capture = true;
-
- // fire any registered events
- if (this.DropDown != null) {
- this.DropDown (this, EventArgs.Empty);
- }
- }
-
- // hide the month calendar
- internal void HideMonthCalendar ()
- {
- this.is_drop_down_visible = false;
- Invalidate (drop_down_arrow_rect);
- month_calendar.Capture = false;
- if (month_calendar.Visible) {
- month_calendar.Hide ();
- }
- }
- // raised by any key down events
- private void KeyPressHandler (object sender, KeyPressEventArgs e) {
- switch (e.KeyChar) {
- default:
- break;
- }
- e.Handled = true;
- }
-
- // // if we lose focus and the drop down is up, then close it
- // private void LostFocusHandler (object sender, EventArgs e)
- // {
- // if (is_drop_down_visible && !month_calendar.Focused) {
- // this.HideMonthCalendar ();
- // }
- // }
-
- // fired when a user clicks on the month calendar to select a date
- private void MonthCalendarDateSelectedHandler (object sender, DateRangeEventArgs e)
- {
- this.Value = e.Start.Date.Add (this.Value.TimeOfDay);
- this.HideMonthCalendar ();
- this.Focus ();
- }
- // to check if the mouse has come down on this control
- private void MouseDownHandler (object sender, MouseEventArgs e)
- {
- /* Click On button*/
- if (ShowUpDown) {
- // TODO: Process clicking for UPDown
- } else {
- if (is_drop_down_visible == false && drop_down_arrow_rect.Contains (e.X, e.Y)) {
- is_drop_down_visible = true;
- Invalidate (drop_down_arrow_rect);
- DropDownMonthCalendar ();
- } else {
- // mouse down on this control anywhere else collapses it
- if (is_drop_down_visible) {
- HideMonthCalendar ();
- }
- }
- }
- }
-
-
- // paint this control now
- private void PaintHandler (object sender, PaintEventArgs pe) {
- if (Width <= 0 || Height <= 0 || Visible == false)
- return;
- Draw (pe.ClipRectangle, pe.Graphics);
- }
-
- private string FormatValue () {
- string ret_value = string.Empty;
- switch (format) {
- case DateTimePickerFormat.Custom:
- // TODO implement custom text formatting
- ret_value = date_value.ToString ();
- break;
- case DateTimePickerFormat.Short:
- ret_value = date_value.ToShortDateString ();
- break;
- case DateTimePickerFormat.Time:
- ret_value = date_value.ToLongTimeString ();
- break;
- default:
- ret_value = date_value.ToLongDateString ();
- break;
- }
- return ret_value;
- }
-
- #endregion
- }
- }
|