473,221 Members | 2,077 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,221 software developers and data experts.

bug using Application.EnableVisualStyles() with datetimepicker control

Guy
I have extended the datetimepicker control to incorporate
a ReadOnly property.
I have used the new keyword to implement my own version
of the value property, so that if readonly == true then
it will not set the value of the control and will leave
the checked status of the checkbox to false when a user
selects a new date.

this works fine when using the control on a win2k machine
but if we use it on a win XP box and call
Application.EnableVisualStyles() then it seems to ignore
my code and check the checkbox and set the value. this is
extremely buggy behaviour! and also the value property
gets called twice (only once on a win2k box).

i have also noticed behaviour changes in the
label.textalignment property when using XP Visual styles
aswell. Below is my implementation of the extended
datetimepicker and also the new data type
(OptionalDateTime) that is used for the value property...

#####LockableDateTimePicker Source###########

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using HCS.DataTypes;

namespace HCS.Generic.UI.Controls
{
/// <summary>
/// LockableDateTimePicker is for selecting
dates. It manipulates the OptionalDateTime
/// class to allow null dates to be handled.
/// </summary>
public class LockableDateTimePicker :
DateTimePicker
{
#region Clean Up Code

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool
disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose
();
}
}
base.Dispose( disposing );
}

#endregion

#region Component Designer generated code
/// <summary>
/// Required method for Designer support -
do not modify
/// the contents of this method with the
code editor.
/// </summary>
private void InitializeComponent()
{
components = new
System.ComponentModel.Container();
}
#endregion

#region Fields

private System.ComponentModel.Container
components = null;
private bool mReadOnly;
private DateTime mDateTime;
private Color mBackColor;
private Color mLockedColor;
private bool mChecked;

#endregion

#region Events

public event OnReadOnlyChangedDelegate
OnReadOnlyChanged;

#endregion

#region EventArgs and Delegates

public class OnReadOnlyChangedEventArgs :
EventArgs
{
private bool mReadOnly;

public OnReadOnlyChangedEventArgs
(bool ReadOnly)
{
mReadOnly = ReadOnly;
}
public bool ReadOnly
{
get
{
return mReadOnly;
}
}
}
public delegate void
OnReadOnlyChangedDelegate(object sender,
OnReadOnlyChangedEventArgs e);

#endregion

#region Constructor

public LockableDateTimePicker()
{
// This call is required by the
Windows.Forms Form Designer.
InitializeComponent();

mBackColor =
base.CalendarMonthBackground;
mLockedColor =
base.CalendarMonthBackground;

//Set defaults for this control
base.Format =
DateTimePickerFormat.Short;

//Make sure that our date backup
is populated
mDateTime = base.Value;
mChecked = base.Checked;
}

#endregion

#region Properties

[DesignerSerializationVisibility
(DesignerSerializationVisibility.Visible)]
public bool ReadOnly
{
get
{
return mReadOnly;
}
set
{
if(value)
{

base.CalendarMonthBackground = mLockedColor;
}
else
{

base.CalendarMonthBackground = mBackColor;
}

mReadOnly = value;
if(OnReadOnlyChanged !=
null)
{
OnReadOnlyChanged
(this, new OnReadOnlyChangedEventArgs(value));
}
}
}

[DesignerSerializationVisibility
(DesignerSerializationVisibility.Visible)]
public Color LockedColor
{
get
{
return mLockedColor;
}
set
{
mLockedColor = value;
}
}

#endregion

#region Public Overridden Properties
public override Color BackColor
{
get
{
return base.BackColor;
}
set
{
mBackColor = value;
if(!mReadOnly)
{
base.BackColor =
value;
}
}
}
public new OptionalDateTime Value
{
set
{
if(value.GetValue() == "")
{
base.Checked =
false;
}
else
{
base.Value =
DateTime.Parse(value.GetValue());
}

}
get
{
if(base.Checked)
{
return new
OptionalDateTime(base.Value);
}
else
{
return new
OptionalDateTime();
}
}
}
#endregion

#region Public Overridden Events

protected override void OnValueChanged
(EventArgs eventargs)
{
base.OnValueChanged (eventargs);

if(mReadOnly)
{
//We need to set the
value of the control back to
//the stored value, since
it is read only
if(base.Value !=
mDateTime)
{
base.Value =
mDateTime;
}
if(base.Checked !=
mChecked)
{
base.Checked =
mChecked;
}
}
else
{
//Store the value for
when it's read only
mDateTime = base.Value;
mChecked = base.Checked;
}
}

#endregion

#region Public Methods
public void Initialise(OptionalDateTime
Value)
{
//Temporarily set the control to
not ReadOnly.
bool mTempReadOnly = mReadOnly;
if(mReadOnly)
{
mReadOnly = false;
}

if(Value.GetValue() == "")
{
base.Checked = false;
mChecked = false;
}
else
{
base.Value =
DateTime.Parse(Value.GetValue());
base.Checked = true;
mDateTime = base.Value;
mChecked = true;
}

//Make sure the ReadOnly value is
returned to normal
mReadOnly = mTempReadOnly;
}
public void Initialise(DateTime Value)
{
Initialise(new OptionalDateTime
(Value));
}
public void Initialise()
{
Initialise(new OptionalDateTime
());
}
#endregion
}
}

##############OptionalDateTime Source##########

[Serializable()]
public class OptionalDateTime
{
#region Enum
/// <summary>
/// Formats available - extend as
required, but remember to update <see cref="GetValue"/>.
/// </summary>
public enum enumDateTimeFormat
{
/// <summary>
/// LongDateFormat
/// </summary>
LongDateFormat,
/// <summary>
/// LongTimeFormat
/// </summary>
LongTimeFormat,
/// <summary>
/// ShortDateFormat
/// </summary>
ShortDateFormat,
/// <summary>
/// ShortTimeFormat
/// </summary>
ShortTimeFormat
}
#endregion

#region Fields
private DateTime mDate;
private bool mIsNull;
#endregion

#region Constructor
/// <summary>
/// Constructor - initialises a null
OptionalDateTime
/// </summary>
public OptionalDateTime()
{
mIsNull = true;
}
/// <summary>
/// Constructor - initialise an
OptionalDateTime to contain the value of a string.
/// If the string is not a valid
DateTime, the object is set to contain a null date.
/// </summary>
/// <param name="value">A string
representing a valid date.</param>
public OptionalDateTime(string value)
{
SetValue(value);
}
/// <summary>
/// Constructor - initialise an
OptionalDateTime to contain the value of a DateTime.
/// </summary>
/// <param name="value">A DateTime value
type.</param>
public OptionalDateTime(DateTime value)
{
SetValue(value);
}
#endregion

#region Public Methods
/// <summary>
/// Set the value of the object to equal
that of a DateTime.
/// </summary>
/// <param name="value">A
DateTime.</param>
public void SetValue(DateTime value)
{
mDate = value;
mIsNull = false;
}
/// <summary>
/// Set the value of the object to equal
that of a string. If the string is not a valid
/// DateTime, the object is set to
contain a null date.
/// </summary>
/// <param name="value">A string
representing a valid date.</param>
public void SetValue(string value)
{
if(value == null || value == "")
{
mIsNull = true;
}
else
{
try
{
mDate =
DateTime.Parse(value);
mIsNull = false;
}
catch
{
throw new
ArgumentException("The string entered cannot be converted
to a DateTime", "value");
}
}
}
/// <summary>
/// Return the value of the object as a
string with optional formatting.
/// </summary>
/// <param name="Format">The format to
return.</param>
/// <returns>A string containing the
correctly formatted date.</returns>
public string GetValue(enumDateTimeFormat
Format)
{
if(mIsNull)
{
return "";
}
else
{
switch(Format)
{
case
enumDateTimeFormat.LongDateFormat:
return
mDate.ToLongDateString();
case
enumDateTimeFormat.LongTimeFormat:
return
mDate.ToLongTimeString();
case
enumDateTimeFormat.ShortDateFormat:
return
mDate.ToShortDateString();
case
enumDateTimeFormat.ShortTimeFormat:
return
mDate.ToShortTimeString();
default:
throw new
UnhandledDateFormatException(Format);
}
}
}
/// <summary>
/// Return the value of the object as a
ShortDateString.
/// </summary>
/// <returns></returns>
public string GetValue()
{
return GetValue
(enumDateTimeFormat.ShortDateFormat);
}
#endregion

#region Public Override Methods
/// <summary>
/// Passes a string containing the date
in <see cref="enumDateTimeFormat.ShortDateFormat"/>.
/// </summary>
/// <returns>The date returned. Passes an
empty string for blank (null) dates.</returns>
public override string ToString()
{
return GetValue();
}
#endregion

#region Properties
/// <summary>
/// Returns the date of the
OptionalDateTime as a DateTime type. Raises the
/// <see
cref="OptionalDateTimeIsNullException"/> if the
OptionalDateTime is
/// blank (null). Check the <see
cref="IsNull"/> property before calling this
/// method to avoid the exception.
/// </summary>
public DateTime GetDateTime
{
get
{
if(mIsNull)
{
throw new
OptionalDateTimeIsNullException();
}
return mDate;
}
}
/// <summary>
/// Gets a boolean value indicating
whether the OptionalDateTime is blank (null).
/// </summary>
public bool IsNull
{
get
{
return mIsNull;
}
}
#endregion
}

thanks in advance
Nov 15 '05 #1
9 3901

Hi Guy,

It is an already known issue.
I will do some research on this to find some workaround for you.
Thanks for you understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Content-Class: urn:content-classes:message
| From: "Guy" <gu*@hcs-ltd.co.uk>
| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| Subject: bug using Application.EnableVisualStyles() with datetimepicker
control
| Date: Fri, 24 Oct 2003 03:56:32 -0700
| Lines: 540
| Message-ID: <08****************************@phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:193774
| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| I have extended the datetimepicker control to incorporate
| a ReadOnly property.
| I have used the new keyword to implement my own version
| of the value property, so that if readonly == true then
| it will not set the value of the control and will leave
| the checked status of the checkbox to false when a user
| selects a new date.
|
| this works fine when using the control on a win2k machine
| but if we use it on a win XP box and call
| Application.EnableVisualStyles() then it seems to ignore
| my code and check the checkbox and set the value. this is
| extremely buggy behaviour! and also the value property
| gets called twice (only once on a win2k box).
|
| i have also noticed behaviour changes in the
| label.textalignment property when using XP Visual styles
| aswell. Below is my implementation of the extended
| datetimepicker and also the new data type
| (OptionalDateTime) that is used for the value property...
|
| #####LockableDateTimePicker Source###########
|
| using System;
| using System.Collections;
| using System.ComponentModel;
| using System.Drawing;
| using System.Data;
| using System.Windows.Forms;
| using HCS.DataTypes;
|
| namespace HCS.Generic.UI.Controls
| {
| /// <summary>
| /// LockableDateTimePicker is for selecting
| dates. It manipulates the OptionalDateTime
| /// class to allow null dates to be handled.
| /// </summary>
| public class LockableDateTimePicker :
| DateTimePicker
| {
| #region Clean Up Code
|
| /// <summary>
| /// Clean up any resources being used.
| /// </summary>
| protected override void Dispose( bool
| disposing )
| {
| if( disposing )
| {
| if(components != null)
| {
| components.Dispose
| ();
| }
| }
| base.Dispose( disposing );
| }
|
| #endregion
|
| #region Component Designer generated code
| /// <summary>
| /// Required method for Designer support -
| do not modify
| /// the contents of this method with the
| code editor.
| /// </summary>
| private void InitializeComponent()
| {
| components = new
| System.ComponentModel.Container();
| }
| #endregion
|
| #region Fields
|
| private System.ComponentModel.Container
| components = null;
| private bool mReadOnly;
| private DateTime mDateTime;
| private Color mBackColor;
| private Color mLockedColor;
| private bool mChecked;
|
| #endregion
|
| #region Events
|
| public event OnReadOnlyChangedDelegate
| OnReadOnlyChanged;
|
| #endregion
|
| #region EventArgs and Delegates
|
| public class OnReadOnlyChangedEventArgs :
| EventArgs
| {
| private bool mReadOnly;
|
| public OnReadOnlyChangedEventArgs
| (bool ReadOnly)
| {
| mReadOnly = ReadOnly;
| }
| public bool ReadOnly
| {
| get
| {
| return mReadOnly;
| }
| }
| }
| public delegate void
| OnReadOnlyChangedDelegate(object sender,
| OnReadOnlyChangedEventArgs e);
|
| #endregion
|
| #region Constructor
|
| public LockableDateTimePicker()
| {
| // This call is required by the
| Windows.Forms Form Designer.
| InitializeComponent();
|
| mBackColor =
| base.CalendarMonthBackground;
| mLockedColor =
| base.CalendarMonthBackground;
|
| //Set defaults for this control
| base.Format =
| DateTimePickerFormat.Short;
|
| //Make sure that our date backup
| is populated
| mDateTime = base.Value;
| mChecked = base.Checked;
| }
|
| #endregion
|
| #region Properties
|
| [DesignerSerializationVisibility
| (DesignerSerializationVisibility.Visible)]
| public bool ReadOnly
| {
| get
| {
| return mReadOnly;
| }
| set
| {
| if(value)
| {
|
| base.CalendarMonthBackground = mLockedColor;
| }
| else
| {
|
| base.CalendarMonthBackground = mBackColor;
| }
|
| mReadOnly = value;
| if(OnReadOnlyChanged !=
| null)
| {
| OnReadOnlyChanged
| (this, new OnReadOnlyChangedEventArgs(value));
| }
| }
| }
|
| [DesignerSerializationVisibility
| (DesignerSerializationVisibility.Visible)]
| public Color LockedColor
| {
| get
| {
| return mLockedColor;
| }
| set
| {
| mLockedColor = value;
| }
| }
|
| #endregion
|
| #region Public Overridden Properties
| public override Color BackColor
| {
| get
| {
| return base.BackColor;
| }
| set
| {
| mBackColor = value;
| if(!mReadOnly)
| {
| base.BackColor =
| value;
| }
| }
| }
| public new OptionalDateTime Value
| {
| set
| {
| if(value.GetValue() == "")
| {
| base.Checked =
| false;
| }
| else
| {
| base.Value =
| DateTime.Parse(value.GetValue());
| }
|
| }
| get
| {
| if(base.Checked)
| {
| return new
| OptionalDateTime(base.Value);
| }
| else
| {
| return new
| OptionalDateTime();
| }
| }
| }
| #endregion
|
| #region Public Overridden Events
|
| protected override void OnValueChanged
| (EventArgs eventargs)
| {
| base.OnValueChanged (eventargs);
|
| if(mReadOnly)
| {
| //We need to set the
| value of the control back to
| //the stored value, since
| it is read only
| if(base.Value !=
| mDateTime)
| {
| base.Value =
| mDateTime;
| }
| if(base.Checked !=
| mChecked)
| {
| base.Checked =
| mChecked;
| }
| }
| else
| {
| //Store the value for
| when it's read only
| mDateTime = base.Value;
| mChecked = base.Checked;
| }
| }
|
| #endregion
|
| #region Public Methods
| public void Initialise(OptionalDateTime
| Value)
| {
| //Temporarily set the control to
| not ReadOnly.
| bool mTempReadOnly = mReadOnly;
| if(mReadOnly)
| {
| mReadOnly = false;
| }
|
| if(Value.GetValue() == "")
| {
| base.Checked = false;
| mChecked = false;
| }
| else
| {
| base.Value =
| DateTime.Parse(Value.GetValue());
| base.Checked = true;
| mDateTime = base.Value;
| mChecked = true;
| }
|
| //Make sure the ReadOnly value is
| returned to normal
| mReadOnly = mTempReadOnly;
| }
| public void Initialise(DateTime Value)
| {
| Initialise(new OptionalDateTime
| (Value));
| }
| public void Initialise()
| {
| Initialise(new OptionalDateTime
| ());
| }
| #endregion
| }
| }
|
| ##############OptionalDateTime Source##########
|
| [Serializable()]
| public class OptionalDateTime
| {
| #region Enum
| /// <summary>
| /// Formats available - extend as
| required, but remember to update <see cref="GetValue"/>.
| /// </summary>
| public enum enumDateTimeFormat
| {
| /// <summary>
| /// LongDateFormat
| /// </summary>
| LongDateFormat,
| /// <summary>
| /// LongTimeFormat
| /// </summary>
| LongTimeFormat,
| /// <summary>
| /// ShortDateFormat
| /// </summary>
| ShortDateFormat,
| /// <summary>
| /// ShortTimeFormat
| /// </summary>
| ShortTimeFormat
| }
| #endregion
|
| #region Fields
| private DateTime mDate;
| private bool mIsNull;
| #endregion
|
| #region Constructor
| /// <summary>
| /// Constructor - initialises a null
| OptionalDateTime
| /// </summary>
| public OptionalDateTime()
| {
| mIsNull = true;
| }
| /// <summary>
| /// Constructor - initialise an
| OptionalDateTime to contain the value of a string.
| /// If the string is not a valid
| DateTime, the object is set to contain a null date.
| /// </summary>
| /// <param name="value">A string
| representing a valid date.</param>
| public OptionalDateTime(string value)
| {
| SetValue(value);
| }
| /// <summary>
| /// Constructor - initialise an
| OptionalDateTime to contain the value of a DateTime.
| /// </summary>
| /// <param name="value">A DateTime value
| type.</param>
| public OptionalDateTime(DateTime value)
| {
| SetValue(value);
| }
| #endregion
|
| #region Public Methods
| /// <summary>
| /// Set the value of the object to equal
| that of a DateTime.
| /// </summary>
| /// <param name="value">A
| DateTime.</param>
| public void SetValue(DateTime value)
| {
| mDate = value;
| mIsNull = false;
| }
| /// <summary>
| /// Set the value of the object to equal
| that of a string. If the string is not a valid
| /// DateTime, the object is set to
| contain a null date.
| /// </summary>
| /// <param name="value">A string
| representing a valid date.</param>
| public void SetValue(string value)
| {
| if(value == null || value == "")
| {
| mIsNull = true;
| }
| else
| {
| try
| {
| mDate =
| DateTime.Parse(value);
| mIsNull = false;
| }
| catch
| {
| throw new
| ArgumentException("The string entered cannot be converted
| to a DateTime", "value");
| }
| }
| }
| /// <summary>
| /// Return the value of the object as a
| string with optional formatting.
| /// </summary>
| /// <param name="Format">The format to
| return.</param>
| /// <returns>A string containing the
| correctly formatted date.</returns>
| public string GetValue(enumDateTimeFormat
| Format)
| {
| if(mIsNull)
| {
| return "";
| }
| else
| {
| switch(Format)
| {
| case
| enumDateTimeFormat.LongDateFormat:
| return
| mDate.ToLongDateString();
| case
| enumDateTimeFormat.LongTimeFormat:
| return
| mDate.ToLongTimeString();
| case
| enumDateTimeFormat.ShortDateFormat:
| return
| mDate.ToShortDateString();
| case
| enumDateTimeFormat.ShortTimeFormat:
| return
| mDate.ToShortTimeString();
| default:
| throw new
| UnhandledDateFormatException(Format);
| }
| }
| }
| /// <summary>
| /// Return the value of the object as a
| ShortDateString.
| /// </summary>
| /// <returns></returns>
| public string GetValue()
| {
| return GetValue
| (enumDateTimeFormat.ShortDateFormat);
| }
| #endregion
|
| #region Public Override Methods
| /// <summary>
| /// Passes a string containing the date
| in <see cref="enumDateTimeFormat.ShortDateFormat"/>.
| /// </summary>
| /// <returns>The date returned. Passes an
| empty string for blank (null) dates.</returns>
| public override string ToString()
| {
| return GetValue();
| }
| #endregion
|
| #region Properties
| /// <summary>
| /// Returns the date of the
| OptionalDateTime as a DateTime type. Raises the
| /// <see
| cref="OptionalDateTimeIsNullException"/> if the
| OptionalDateTime is
| /// blank (null). Check the <see
| cref="IsNull"/> property before calling this
| /// method to avoid the exception.
| /// </summary>
| public DateTime GetDateTime
| {
| get
| {
| if(mIsNull)
| {
| throw new
| OptionalDateTimeIsNullException();
| }
| return mDate;
| }
| }
| /// <summary>
| /// Gets a boolean value indicating
| whether the OptionalDateTime is blank (null).
| /// </summary>
| public bool IsNull
| {
| get
| {
| return mIsNull;
| }
| }
| #endregion
| }
|
| thanks in advance
|

Nov 15 '05 #2
guy
Ok Jeffrey, ill wait for your reply
-----Original Message-----

Hi Guy,

It is an already known issue.
I will do some research on this to find some workaround for you.Thanks for you understanding.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
--------------------
| Content-Class: urn:content-classes:message
| From: "Guy" <gu*@hcs-ltd.co.uk>
| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| Subject: bug using Application.EnableVisualStyles() with datetimepickercontrol
| Date: Fri, 24 Oct 2003 03:56:32 -0700
| Lines: 540
| Message-ID: <08****************************@phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300| Newsgroups: microsoft.public.dotnet.languages.csharp
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:193774| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| I have extended the datetimepicker control to incorporate| a ReadOnly property.
| I have used the new keyword to implement my own version| of the value property, so that if readonly == true then| it will not set the value of the control and will leave| the checked status of the checkbox to false when a user| selects a new date.
|
| this works fine when using the control on a win2k machine| but if we use it on a win XP box and call
| Application.EnableVisualStyles() then it seems to ignore| my code and check the checkbox and set the value. this is| extremely buggy behaviour! and also the value property
| gets called twice (only once on a win2k box).
|
| i have also noticed behaviour changes in the
| label.textalignment property when using XP Visual styles| aswell. Below is my implementation of the extended
| datetimepicker and also the new data type
| (OptionalDateTime) that is used for the value property...|
| #####LockableDateTimePicker Source###########
|
| using System;
| using System.Collections;
| using System.ComponentModel;
| using System.Drawing;
| using System.Data;
| using System.Windows.Forms;
| using HCS.DataTypes;
|
| namespace HCS.Generic.UI.Controls
| {
| /// <summary>
| /// LockableDateTimePicker is for selecting
| dates. It manipulates the OptionalDateTime
| /// class to allow null dates to be handled.
| /// </summary>
| public class LockableDateTimePicker :
| DateTimePicker
| {
| #region Clean Up Code
|
| /// <summary>
| /// Clean up any resources being used.
| /// </summary>
| protected override void Dispose( bool
| disposing )
| {
| if( disposing )
| {
| if(components != null)
| {
| components.Dispose
| ();
| }
| }
| base.Dispose( disposing );
| }
|
| #endregion
|
| #region Component Designer generated code
| /// <summary>
| /// Required method for Designer support -
| do not modify
| /// the contents of this method with the
| code editor.
| /// </summary>
| private void InitializeComponent()
| {
| components = new
| System.ComponentModel.Container();
| }
| #endregion
|
| #region Fields
|
| private System.ComponentModel.Container
| components = null;
| private bool mReadOnly;
| private DateTime mDateTime;
| private Color mBackColor;
| private Color mLockedColor;
| private bool mChecked;
|
| #endregion
|
| #region Events
|
| public event OnReadOnlyChangedDelegate
| OnReadOnlyChanged;
|
| #endregion
|
| #region EventArgs and Delegates
|
| public class OnReadOnlyChangedEventArgs :
| EventArgs
| {
| private bool mReadOnly;
|
| public OnReadOnlyChangedEventArgs
| (bool ReadOnly)
| {
| mReadOnly = ReadOnly;
| }
| public bool ReadOnly
| {
| get
| {
| return mReadOnly;
| }
| }
| }
| public delegate void
| OnReadOnlyChangedDelegate(object sender,
| OnReadOnlyChangedEventArgs e);
|
| #endregion
|
| #region Constructor
|
| public LockableDateTimePicker()
| {
| // This call is required by the
| Windows.Forms Form Designer.
| InitializeComponent();
|
| mBackColor =
| base.CalendarMonthBackground;
| mLockedColor =
| base.CalendarMonthBackground;
|
| //Set defaults for this control
| base.Format =
| DateTimePickerFormat.Short;
|
| //Make sure that our date backup
| is populated
| mDateTime = base.Value;
| mChecked = base.Checked;
| }
|
| #endregion
|
| #region Properties
|
| [DesignerSerializationVisibility
| (DesignerSerializationVisibility.Visible)]
| public bool ReadOnly
| {
| get
| {
| return mReadOnly;
| }
| set
| {
| if(value)
| {
|
| base.CalendarMonthBackground = mLockedColor;
| }
| else
| {
|
| base.CalendarMonthBackground = mBackColor;
| }
|
| mReadOnly = value;
| if(OnReadOnlyChanged !=
| null)
| {
| OnReadOnlyChanged
| (this, new OnReadOnlyChangedEventArgs(value));
| }
| }
| }
|
| [DesignerSerializationVisibility
| (DesignerSerializationVisibility.Visible)]
| public Color LockedColor
| {
| get
| {
| return mLockedColor;
| }
| set
| {
| mLockedColor = value;
| }
| }
|
| #endregion
|
| #region Public Overridden Properties
| public override Color BackColor
| {
| get
| {
| return base.BackColor;
| }
| set
| {
| mBackColor = value;
| if(!mReadOnly)
| {
| base.BackColor =
| value;
| }
| }
| }
| public new OptionalDateTime Value
| {
| set
| {
| if(value.GetValue() == "")
| {
| base.Checked =
| false;
| }
| else
| {
| base.Value =
| DateTime.Parse(value.GetValue());
| }
|
| }
| get
| {
| if(base.Checked)
| {
| return new
| OptionalDateTime(base.Value);
| }
| else
| {
| return new
| OptionalDateTime();
| }
| }
| }
| #endregion
|
| #region Public Overridden Events
|
| protected override void OnValueChanged
| (EventArgs eventargs)
| {
| base.OnValueChanged (eventargs);
|
| if(mReadOnly)
| {
| //We need to set the
| value of the control back to
| //the stored value, since
| it is read only
| if(base.Value !=
| mDateTime)
| {
| base.Value =
| mDateTime;
| }
| if(base.Checked !=
| mChecked)
| {
| base.Checked =
| mChecked;
| }
| }
| else
| {
| //Store the value for
| when it's read only
| mDateTime = base.Value;
| mChecked = base.Checked;
| }
| }
|
| #endregion
|
| #region Public Methods
| public void Initialise(OptionalDateTime
| Value)
| {
| //Temporarily set the control to
| not ReadOnly.
| bool mTempReadOnly = mReadOnly;
| if(mReadOnly)
| {
| mReadOnly = false;
| }
|
| if(Value.GetValue() == "")
| {
| base.Checked = false;
| mChecked = false;
| }
| else
| {
| base.Value =
| DateTime.Parse(Value.GetValue());
| base.Checked = true;
| mDateTime = base.Value;
| mChecked = true;
| }
|
| //Make sure the ReadOnly value is
| returned to normal
| mReadOnly = mTempReadOnly;
| }
| public void Initialise(DateTime Value)
| {
| Initialise(new OptionalDateTime
| (Value));
| }
| public void Initialise()
| {
| Initialise(new OptionalDateTime
| ());
| }
| #endregion
| }
| }
|
| ##############OptionalDateTime Source##########
|
| [Serializable()]
| public class OptionalDateTime
| {
| #region Enum
| /// <summary>
| /// Formats available - extend as
| required, but remember to update <see cref="GetValue"/>.| /// </summary>
| public enum enumDateTimeFormat
| {
| /// <summary>
| /// LongDateFormat
| /// </summary>
| LongDateFormat,
| /// <summary>
| /// LongTimeFormat
| /// </summary>
| LongTimeFormat,
| /// <summary>
| /// ShortDateFormat
| /// </summary>
| ShortDateFormat,
| /// <summary>
| /// ShortTimeFormat
| /// </summary>
| ShortTimeFormat
| }
| #endregion
|
| #region Fields
| private DateTime mDate;
| private bool mIsNull;
| #endregion
|
| #region Constructor
| /// <summary>
| /// Constructor - initialises a null
| OptionalDateTime
| /// </summary>
| public OptionalDateTime()
| {
| mIsNull = true;
| }
| /// <summary>
| /// Constructor - initialise an
| OptionalDateTime to contain the value of a string.
| /// If the string is not a valid
| DateTime, the object is set to contain a null date.
| /// </summary>
| /// <param name="value">A string
| representing a valid date.</param>
| public OptionalDateTime(string value)
| {
| SetValue(value);
| }
| /// <summary>
| /// Constructor - initialise an
| OptionalDateTime to contain the value of a DateTime.
| /// </summary>
| /// <param name="value">A DateTime value
| type.</param>
| public OptionalDateTime(DateTime value)
| {
| SetValue(value);
| }
| #endregion
|
| #region Public Methods
| /// <summary>
| /// Set the value of the object to equal
| that of a DateTime.
| /// </summary>
| /// <param name="value">A
| DateTime.</param>
| public void SetValue(DateTime value)
| {
| mDate = value;
| mIsNull = false;
| }
| /// <summary>
| /// Set the value of the object to equal
| that of a string. If the string is not a valid
| /// DateTime, the object is set to
| contain a null date.
| /// </summary>
| /// <param name="value">A string
| representing a valid date.</param>
| public void SetValue(string value)
| {
| if(value == null || value == "")
| {
| mIsNull = true;
| }
| else
| {
| try
| {
| mDate =
| DateTime.Parse(value);
| mIsNull = false;
| }
| catch
| {
| throw new
| ArgumentException("The string entered cannot be converted| to a DateTime", "value");
| }
| }
| }
| /// <summary>
| /// Return the value of the object as a
| string with optional formatting.
| /// </summary>
| /// <param name="Format">The format to
| return.</param>
| /// <returns>A string containing the
| correctly formatted date.</returns>
| public string GetValue(enumDateTimeFormat
| Format)
| {
| if(mIsNull)
| {
| return "";
| }
| else
| {
| switch(Format)
| {
| case
| enumDateTimeFormat.LongDateFormat:
| return
| mDate.ToLongDateString();
| case
| enumDateTimeFormat.LongTimeFormat:
| return
| mDate.ToLongTimeString();
| case
| enumDateTimeFormat.ShortDateFormat:
| return
| mDate.ToShortDateString();
| case
| enumDateTimeFormat.ShortTimeFormat:
| return
| mDate.ToShortTimeString();
| default:
| throw new
| UnhandledDateFormatException(Format);
| }
| }
| }
| /// <summary>
| /// Return the value of the object as a
| ShortDateString.
| /// </summary>
| /// <returns></returns>
| public string GetValue()
| {
| return GetValue
| (enumDateTimeFormat.ShortDateFormat);
| }
| #endregion
|
| #region Public Override Methods
| /// <summary>
| /// Passes a string containing the date
| in <see cref="enumDateTimeFormat.ShortDateFormat"/>.
| /// </summary>
| /// <returns>The date returned. Passes an
| empty string for blank (null) dates.</returns>
| public override string ToString()
| {
| return GetValue();
| }
| #endregion
|
| #region Properties
| /// <summary>
| /// Returns the date of the
| OptionalDateTime as a DateTime type. Raises the
| /// <see
| cref="OptionalDateTimeIsNullException"/> if the
| OptionalDateTime is
| /// blank (null). Check the <see
| cref="IsNull"/> property before calling this
| /// method to avoid the exception.
| /// </summary>
| public DateTime GetDateTime
| {
| get
| {
| if(mIsNull)
| {
| throw new
| OptionalDateTimeIsNullException();
| }
| return mDate;
| }
| }
| /// <summary>
| /// Gets a boolean value indicating
| whether the OptionalDateTime is blank (null).
| /// </summary>
| public bool IsNull
| {
| get
| {
| return mIsNull;
| }
| }
| #endregion
| }
|
| thanks in advance
|

.

Nov 15 '05 #3

Hi Guy,

Sorry for letting you waiting so long time.
In this time, I did a lot of research into DateTimePicker control and
wanted to find a workaround for you.
Here, I provide you 2 ways of workaround:
First: override its OnCloseUp method and reset its value to its original
value. But this is not enough, when you open the datetimepicker, you can
use keyboard arrow to navigate the selection, and the value displayed will
also change in the textbox( For the moment, we call it textbox). I think we
should not let this happen, the value should stay the same. But just reset
value in the OnValueChanged method seems work well on keyboard navigation,
but will again change the value when closing the calendar.(It seems that
the OnCloseUp abated). So I hooked into this control, and filter its
MCN_SELCHANGE notification in WM_NOTIFY message.

using System.Runtime .InteropServices ;
public bool readonlyval=false;
private DateTime oldval;

protected override void OnCloseUp(EventArgs eventargs)
{
if(readonlyval==true)
{
this.Value =oldval;
}
oldval=this.Value ;
base.OnCloseUp (eventargs);
}

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=MCN_FIRST + 1;
private int WM_NOTIFY=0x004E;

[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(m.Msg==WM_NOTIFY)
{
if(m.HWnd==this.Handle)
{
NMHDR nm1=(NMHDR)Marshal.PtrToStructure(m.LParam,typeof( NMHDR));
if(nm1.code==MCN_SELCHANGE)
{
return;
}
}
}
base.WndProc (ref m);
}

I use Spy++ to find that the DateTimePicker control will receive WM_NOTIFY
message with MCN_SELCHANGE code when selection changes.
All the const value MCN_SELCHANGE, MCN_FIRST can be found in the C:\Program
Files\Microsoft Visual Studio\VC98\Include directory *.h files.

It works well on my machine. If you have any question, please feel free to
tell me.
I will reply the second way of workaround in another reply post.

Best regards
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Content-Class: urn:content-classes:message
| From: "guy" <gu*@hcs-ltd.co.uk>
| Sender: "guy" <gu*@hcs-ltd.co.uk>
| References: <08****************************@phx.gbl>
<6i**************@cpmsftngxa06.phx.gbl>
| Subject: RE: bug using Application.EnableVisualStyles() with
datetimepicker control
| Date: Tue, 28 Oct 2003 01:26:56 -0800
| Lines: 601
| Message-ID: <08****************************@phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Thread-Index: AcOdNaFMO+yabmhBTea+z5L0ii9kXg==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:194627
| NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Ok Jeffrey, ill wait for your reply
|
|
|
| >-----Original Message-----
| >
| >Hi Guy,
| >
| >It is an already known issue.
| >I will do some research on this to find some workaround
| for you.
| >Thanks for you understanding.
| >
| >Best regards,
| >Jeffrey Tan
| >Microsoft Online Partner Support
| >Get Secure! - www.microsoft.com/security
| >This posting is provided "as is" with no warranties and
| confers no rights.
| >
| >--------------------
| >| Content-Class: urn:content-classes:message
| >| From: "Guy" <gu*@hcs-ltd.co.uk>
| >| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| >| Subject: bug using Application.EnableVisualStyles()
| with datetimepicker
| >control
| >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| >| Lines: 540
| >| Message-ID: <08****************************@phx.gbl>
| >| MIME-Version: 1.0
| >| Content-Type: text/plain;
| >| charset="iso-8859-1"
| >| Content-Transfer-Encoding: 7bit
| >| X-Newsreader: Microsoft CDO for Windows 2000
| >| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| >| X-MimeOLE: Produced By Microsoft MimeOLE
| V5.50.4910.0300
| >| Newsgroups: microsoft.public.dotnet.languages.csharp
| >| Path: cpmsftngxa06.phx.gbl
| >| Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:193774
| >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| >| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| >|
| >| I have extended the datetimepicker control to
| incorporate
| >| a ReadOnly property.
| >| I have used the new keyword to implement my own
| version
| >| of the value property, so that if readonly == true
| then
| >| it will not set the value of the control and will
| leave
| >| the checked status of the checkbox to false when a
| user
| >| selects a new date.
| >|
| >| this works fine when using the control on a win2k
| machine
| >| but if we use it on a win XP box and call
| >| Application.EnableVisualStyles() then it seems to
| ignore
| >| my code and check the checkbox and set the value. this
| is
| >| extremely buggy behaviour! and also the value property
| >| gets called twice (only once on a win2k box).
| >|
| >| i have also noticed behaviour changes in the
| >| label.textalignment property when using XP Visual
| styles
| >| aswell. Below is my implementation of the extended
| >| datetimepicker and also the new data type
| >| (OptionalDateTime) that is used for the value
| property...
| >|
| >| #####LockableDateTimePicker Source###########
| >|
| >| using System;
| >| using System.Collections;
| >| using System.ComponentModel;
| >| using System.Drawing;
| >| using System.Data;
| >| using System.Windows.Forms;
| >| using HCS.DataTypes;
| >|
| >| namespace HCS.Generic.UI.Controls
| >| {
| >| /// <summary>
| >| /// LockableDateTimePicker is for selecting
| >| dates. It manipulates the OptionalDateTime
| >| /// class to allow null dates to be handled.
| >| /// </summary>
| >| public class LockableDateTimePicker :
| >| DateTimePicker
| >| {
| >| #region Clean Up Code
| >|
| >| /// <summary>
| >| /// Clean up any resources being used.
| >| /// </summary>
| >| protected override void Dispose( bool
| >| disposing )
| >| {
| >| if( disposing )
| >| {
| >| if(components != null)
| >| {
| >| components.Dispose
| >| ();
| >| }
| >| }
| >| base.Dispose( disposing );
| >| }
| >|
| >| #endregion
| >|
| >| #region Component Designer generated code
| >| /// <summary>
| >| /// Required method for Designer support -
| >| do not modify
| >| /// the contents of this method with the
| >| code editor.
| >| /// </summary>
| >| private void InitializeComponent()
| >| {
| >| components = new
| >| System.ComponentModel.Container();
| >| }
| >| #endregion
| >|
| >| #region Fields
| >|
| >| private System.ComponentModel.Container
| >| components = null;
| >| private bool mReadOnly;
| >| private DateTime mDateTime;
| >| private Color mBackColor;
| >| private Color mLockedColor;
| >| private bool mChecked;
| >|
| >| #endregion
| >|
| >| #region Events
| >|
| >| public event OnReadOnlyChangedDelegate
| >| OnReadOnlyChanged;
| >|
| >| #endregion
| >|
| >| #region EventArgs and Delegates
| >|
| >| public class OnReadOnlyChangedEventArgs :
| >| EventArgs
| >| {
| >| private bool mReadOnly;
| >|
| >| public OnReadOnlyChangedEventArgs
| >| (bool ReadOnly)
| >| {
| >| mReadOnly = ReadOnly;
| >| }
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| }
| >| }
| >| public delegate void
| >| OnReadOnlyChangedDelegate(object sender,
| >| OnReadOnlyChangedEventArgs e);
| >|
| >| #endregion
| >|
| >| #region Constructor
| >|
| >| public LockableDateTimePicker()
| >| {
| >| // This call is required by the
| >| Windows.Forms Form Designer.
| >| InitializeComponent();
| >|
| >| mBackColor =
| >| base.CalendarMonthBackground;
| >| mLockedColor =
| >| base.CalendarMonthBackground;
| >|
| >| //Set defaults for this control
| >| base.Format =
| >| DateTimePickerFormat.Short;
| >|
| >| //Make sure that our date backup
| >| is populated
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >|
| >| #endregion
| >|
| >| #region Properties
| >|
| >| [DesignerSerializationVisibility
| >| (DesignerSerializationVisibility.Visible)]
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| set
| >| {
| >| if(value)
| >| {
| >|
| >| base.CalendarMonthBackground = mLockedColor;
| >| }
| >| else
| >| {
| >|
| >| base.CalendarMonthBackground = mBackColor;
| >| }
| >|
| >| mReadOnly = value;
| >| if(OnReadOnlyChanged !=
| >| null)
| >| {
| >| OnReadOnlyChanged
| >| (this, new OnReadOnlyChangedEventArgs(value));
| >| }
| >| }
| >| }
| >|
| >| [DesignerSerializationVisibility
| >| (DesignerSerializationVisibility.Visible)]
| >| public Color LockedColor
| >| {
| >| get
| >| {
| >| return mLockedColor;
| >| }
| >| set
| >| {
| >| mLockedColor = value;
| >| }
| >| }
| >|
| >| #endregion
| >|
| >| #region Public Overridden Properties
| >| public override Color BackColor
| >| {
| >| get
| >| {
| >| return base.BackColor;
| >| }
| >| set
| >| {
| >| mBackColor = value;
| >| if(!mReadOnly)
| >| {
| >| base.BackColor =
| >| value;
| >| }
| >| }
| >| }
| >| public new OptionalDateTime Value
| >| {
| >| set
| >| {
| >| if(value.GetValue() == "")
| >| {
| >| base.Checked =
| >| false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse(value.GetValue());
| >| }
| >|
| >| }
| >| get
| >| {
| >| if(base.Checked)
| >| {
| >| return new
| >| OptionalDateTime(base.Value);
| >| }
| >| else
| >| {
| >| return new
| >| OptionalDateTime();
| >| }
| >| }
| >| }
| >| #endregion
| >|
| >| #region Public Overridden Events
| >|
| >| protected override void OnValueChanged
| >| (EventArgs eventargs)
| >| {
| >| base.OnValueChanged (eventargs);
| >|
| >| if(mReadOnly)
| >| {
| >| //We need to set the
| >| value of the control back to
| >| //the stored value, since
| >| it is read only
| >| if(base.Value !=
| >| mDateTime)
| >| {
| >| base.Value =
| >| mDateTime;
| >| }
| >| if(base.Checked !=
| >| mChecked)
| >| {
| >| base.Checked =
| >| mChecked;
| >| }
| >| }
| >| else
| >| {
| >| //Store the value for
| >| when it's read only
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >| }
| >|
| >| #endregion
| >|
| >| #region Public Methods
| >| public void Initialise(OptionalDateTime
| >| Value)
| >| {
| >| //Temporarily set the control to
| >| not ReadOnly.
| >| bool mTempReadOnly = mReadOnly;
| >| if(mReadOnly)
| >| {
| >| mReadOnly = false;
| >| }
| >|
| >| if(Value.GetValue() == "")
| >| {
| >| base.Checked = false;
| >| mChecked = false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse(Value.GetValue());
| >| base.Checked = true;
| >| mDateTime = base.Value;
| >| mChecked = true;
| >| }
| >|
| >| //Make sure the ReadOnly value is
| >| returned to normal
| >| mReadOnly = mTempReadOnly;
| >| }
| >| public void Initialise(DateTime Value)
| >| {
| >| Initialise(new OptionalDateTime
| >| (Value));
| >| }
| >| public void Initialise()
| >| {
| >| Initialise(new OptionalDateTime
| >| ());
| >| }
| >| #endregion
| >| }
| >| }
| >|
| >| ##############OptionalDateTime Source##########
| >|
| >| [Serializable()]
| >| public class OptionalDateTime
| >| {
| >| #region Enum
| >| /// <summary>
| >| /// Formats available - extend as
| >| required, but remember to update <see
| cref="GetValue"/>.
| >| /// </summary>
| >| public enum enumDateTimeFormat
| >| {
| >| /// <summary>
| >| /// LongDateFormat
| >| /// </summary>
| >| LongDateFormat,
| >| /// <summary>
| >| /// LongTimeFormat
| >| /// </summary>
| >| LongTimeFormat,
| >| /// <summary>
| >| /// ShortDateFormat
| >| /// </summary>
| >| ShortDateFormat,
| >| /// <summary>
| >| /// ShortTimeFormat
| >| /// </summary>
| >| ShortTimeFormat
| >| }
| >| #endregion
| >|
| >| #region Fields
| >| private DateTime mDate;
| >| private bool mIsNull;
| >| #endregion
| >|
| >| #region Constructor
| >| /// <summary>
| >| /// Constructor - initialises a null
| >| OptionalDateTime
| >| /// </summary>
| >| public OptionalDateTime()
| >| {
| >| mIsNull = true;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTime to contain the value of a string.
| >| /// If the string is not a valid
| >| DateTime, the object is set to contain a null date.
| >| /// </summary>
| >| /// <param name="value">A string
| >| representing a valid date.</param>
| >| public OptionalDateTime(string value)
| >| {
| >| SetValue(value);
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTime to contain the value of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A DateTime value
| >| type.</param>
| >| public OptionalDateTime(DateTime value)
| >| {
| >| SetValue(value);
| >| }
| >| #endregion
| >|
| >| #region Public Methods
| >| /// <summary>
| >| /// Set the value of the object to equal
| >| that of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A
| >| DateTime.</param>
| >| public void SetValue(DateTime value)
| >| {
| >| mDate = value;
| >| mIsNull = false;
| >| }
| >| /// <summary>
| >| /// Set the value of the object to equal
| >| that of a string. If the string is not a valid
| >| /// DateTime, the object is set to
| >| contain a null date.
| >| /// </summary>
| >| /// <param name="value">A string
| >| representing a valid date.</param>
| >| public void SetValue(string value)
| >| {
| >| if(value == null || value == "")
| >| {
| >| mIsNull = true;
| >| }
| >| else
| >| {
| >| try
| >| {
| >| mDate =
| >| DateTime.Parse(value);
| >| mIsNull = false;
| >| }
| >| catch
| >| {
| >| throw new
| >| ArgumentException("The string entered cannot be
| converted
| >| to a DateTime", "value");
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| string with optional formatting.
| >| /// </summary>
| >| /// <param name="Format">The format to
| >| return.</param>
| >| /// <returns>A string containing the
| >| correctly formatted date.</returns>
| >| public string GetValue(enumDateTimeFormat
| >| Format)
| >| {
| >| if(mIsNull)
| >| {
| >| return "";
| >| }
| >| else
| >| {
| >| switch(Format)
| >| {
| >| case
| >| enumDateTimeFormat.LongDateFormat:
| >| return
| >| mDate.ToLongDateString();
| >| case
| >| enumDateTimeFormat.LongTimeFormat:
| >| return
| >| mDate.ToLongTimeString();
| >| case
| >| enumDateTimeFormat.ShortDateFormat:
| >| return
| >| mDate.ToShortDateString();
| >| case
| >| enumDateTimeFormat.ShortTimeFormat:
| >| return
| >| mDate.ToShortTimeString();
| >| default:
| >| throw new
| >| UnhandledDateFormatException(Format);
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| ShortDateString.
| >| /// </summary>
| >| /// <returns></returns>
| >| public string GetValue()
| >| {
| >| return GetValue
| >| (enumDateTimeFormat.ShortDateFormat);
| >| }
| >| #endregion
| >|
| >| #region Public Override Methods
| >| /// <summary>
| >| /// Passes a string containing the date
| >| in <see cref="enumDateTimeFormat.ShortDateFormat"/>.
| >| /// </summary>
| >| /// <returns>The date returned. Passes an
| >| empty string for blank (null) dates.</returns>
| >| public override string ToString()
| >| {
| >| return GetValue();
| >| }
| >| #endregion
| >|
| >| #region Properties
| >| /// <summary>
| >| /// Returns the date of the
| >| OptionalDateTime as a DateTime type. Raises the
| >| /// <see
| >| cref="OptionalDateTimeIsNullException"/> if the
| >| OptionalDateTime is
| >| /// blank (null). Check the <see
| >| cref="IsNull"/> property before calling this
| >| /// method to avoid the exception.
| >| /// </summary>
| >| public DateTime GetDateTime
| >| {
| >| get
| >| {
| >| if(mIsNull)
| >| {
| >| throw new
| >| OptionalDateTimeIsNullException();
| >| }
| >| return mDate;
| >| }
| >| }
| >| /// <summary>
| >| /// Gets a boolean value indicating
| >| whether the OptionalDateTime is blank (null).
| >| /// </summary>
| >| public bool IsNull
| >| {
| >| get
| >| {
| >| return mIsNull;
| >| }
| >| }
| >| #endregion
| >| }
| >|
| >| thanks in advance
| >|
| >
| >.
| >
|

Nov 15 '05 #4

Sorry, there should be a "oldval=this.Value ;" in Custom DateTimePicker's
constructor.

Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Newsgroups: microsoft.public.dotnet.languages.csharp
| From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| Organization: Microsoft
| Date: Wed, 29 Oct 2003 03:12:29 GMT
| Subject: RE: bug using Application.EnableVisualStyles() with
datetimepicker control
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
|
|
| Hi Guy,
|
| Sorry for letting you waiting so long time.
| In this time, I did a lot of research into DateTimePicker control and
| wanted to find a workaround for you.
| Here, I provide you 2 ways of workaround:
| First: override its OnCloseUp method and reset its value to its original
| value. But this is not enough, when you open the datetimepicker, you can
| use keyboard arrow to navigate the selection, and the value displayed
will
| also change in the textbox( For the moment, we call it textbox). I think
we
| should not let this happen, the value should stay the same. But just
reset
| value in the OnValueChanged method seems work well on keyboard
navigation,
| but will again change the value when closing the calendar.(It seems that
| the OnCloseUp abated). So I hooked into this control, and filter its
| MCN_SELCHANGE notification in WM_NOTIFY message.
|
| using System.Runtime .InteropServices ;
| public bool readonlyval=false;
| private DateTime oldval;
|
| protected override void OnCloseUp(EventArgs eventargs)
| {
| if(readonlyval==true)
| {
| this.Value =oldval;
| }
| oldval=this.Value ;
| base.OnCloseUp (eventargs);
| }
|
| private const int MCN_FIRST=-750;
| private const int MCN_SELCHANGE=MCN_FIRST + 1;
| private int WM_NOTIFY=0x004E;
|
| [StructLayout(LayoutKind.Sequential)]
| public struct NMHDR
| {
| public IntPtr hwndFrom;
| public int idfrom;
| public int code;
| }
|
| protected override void WndProc(ref Message m)
| {
| if(m.Msg==WM_NOTIFY)
| {
| if(m.HWnd==this.Handle)
| {
| NMHDR nm1=(NMHDR)Marshal.PtrToStructure(m.LParam,typeof( NMHDR));
| if(nm1.code==MCN_SELCHANGE)
| {
| return;
| }
| }
| }
| base.WndProc (ref m);
| }
|
| I use Spy++ to find that the DateTimePicker control will receive
WM_NOTIFY
| message with MCN_SELCHANGE code when selection changes.
| All the const value MCN_SELCHANGE, MCN_FIRST can be found in the
C:\Program
| Files\Microsoft Visual Studio\VC98\Include directory *.h files.
|
| It works well on my machine. If you have any question, please feel free
to
| tell me.
| I will reply the second way of workaround in another reply post.
|
| Best regards
| Jeffrey Tan
| Microsoft Online Partner Support
| Get Secure! - www.microsoft.com/security
| This posting is provided "as is" with no warranties and confers no rights.
|
| --------------------
| | Content-Class: urn:content-classes:message
| | From: "guy" <gu*@hcs-ltd.co.uk>
| | Sender: "guy" <gu*@hcs-ltd.co.uk>
| | References: <08****************************@phx.gbl>
| <6i**************@cpmsftngxa06.phx.gbl>
| | Subject: RE: bug using Application.EnableVisualStyles() with
| datetimepicker control
| | Date: Tue, 28 Oct 2003 01:26:56 -0800
| | Lines: 601
| | Message-ID: <08****************************@phx.gbl>
| | MIME-Version: 1.0
| | Content-Type: text/plain;
| | charset="iso-8859-1"
| | Content-Transfer-Encoding: 7bit
| | X-Newsreader: Microsoft CDO for Windows 2000
| | Thread-Index: AcOdNaFMO+yabmhBTea+z5L0ii9kXg==
| | X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| | Newsgroups: microsoft.public.dotnet.languages.csharp
| | Path: cpmsftngxa06.phx.gbl
| | Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.languages.csharp:194627
| | NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| |
| | Ok Jeffrey, ill wait for your reply
| |
| |
| |
| | >-----Original Message-----
| | >
| | >Hi Guy,
| | >
| | >It is an already known issue.
| | >I will do some research on this to find some workaround
| | for you.
| | >Thanks for you understanding.
| | >
| | >Best regards,
| | >Jeffrey Tan
| | >Microsoft Online Partner Support
| | >Get Secure! - www.microsoft.com/security
| | >This posting is provided "as is" with no warranties and
| | confers no rights.
| | >
| | >--------------------
| | >| Content-Class: urn:content-classes:message
| | >| From: "Guy" <gu*@hcs-ltd.co.uk>
| | >| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| | >| Subject: bug using Application.EnableVisualStyles()
| | with datetimepicker
| | >control
| | >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| | >| Lines: 540
| | >| Message-ID: <08****************************@phx.gbl>
| | >| MIME-Version: 1.0
| | >| Content-Type: text/plain;
| | >| charset="iso-8859-1"
| | >| Content-Transfer-Encoding: 7bit
| | >| X-Newsreader: Microsoft CDO for Windows 2000
| | >| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| | >| X-MimeOLE: Produced By Microsoft MimeOLE
| | V5.50.4910.0300
| | >| Newsgroups: microsoft.public.dotnet.languages.csharp
| | >| Path: cpmsftngxa06.phx.gbl
| | >| Xref: cpmsftngxa06.phx.gbl
| | microsoft.public.dotnet.languages.csharp:193774
| | >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| | >| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| | >|
| | >| I have extended the datetimepicker control to
| | incorporate
| | >| a ReadOnly property.
| | >| I have used the new keyword to implement my own
| | version
| | >| of the value property, so that if readonly == true
| | then
| | >| it will not set the value of the control and will
| | leave
| | >| the checked status of the checkbox to false when a
| | user
| | >| selects a new date.
| | >|
| | >| this works fine when using the control on a win2k
| | machine
| | >| but if we use it on a win XP box and call
| | >| Application.EnableVisualStyles() then it seems to
| | ignore
| | >| my code and check the checkbox and set the value. this
| | is
| | >| extremely buggy behaviour! and also the value property
| | >| gets called twice (only once on a win2k box).
| | >|
| | >| i have also noticed behaviour changes in the
| | >| label.textalignment property when using XP Visual
| | styles
| | >| aswell. Below is my implementation of the extended
| | >| datetimepicker and also the new data type
| | >| (OptionalDateTime) that is used for the value
| | property...
| | >|
| | >| #####LockableDateTimePicker Source###########
| | >|
| | >| using System;
| | >| using System.Collections;
| | >| using System.ComponentModel;
| | >| using System.Drawing;
| | >| using System.Data;
| | >| using System.Windows.Forms;
| | >| using HCS.DataTypes;
| | >|
| | >| namespace HCS.Generic.UI.Controls
| | >| {
| | >| /// <summary>
| | >| /// LockableDateTimePicker is for selecting
| | >| dates. It manipulates the OptionalDateTime
| | >| /// class to allow null dates to be handled.
| | >| /// </summary>
| | >| public class LockableDateTimePicker :
| | >| DateTimePicker
| | >| {
| | >| #region Clean Up Code
| | >|
| | >| /// <summary>
| | >| /// Clean up any resources being used.
| | >| /// </summary>
| | >| protected override void Dispose( bool
| | >| disposing )
| | >| {
| | >| if( disposing )
| | >| {
| | >| if(components != null)
| | >| {
| | >| components.Dispose
| | >| ();
| | >| }
| | >| }
| | >| base.Dispose( disposing );
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Component Designer generated code
| | >| /// <summary>
| | >| /// Required method for Designer support -
| | >| do not modify
| | >| /// the contents of this method with the
| | >| code editor.
| | >| /// </summary>
| | >| private void InitializeComponent()
| | >| {
| | >| components = new
| | >| System.ComponentModel.Container();
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >|
| | >| private System.ComponentModel.Container
| | >| components = null;
| | >| private bool mReadOnly;
| | >| private DateTime mDateTime;
| | >| private Color mBackColor;
| | >| private Color mLockedColor;
| | >| private bool mChecked;
| | >|
| | >| #endregion
| | >|
| | >| #region Events
| | >|
| | >| public event OnReadOnlyChangedDelegate
| | >| OnReadOnlyChanged;
| | >|
| | >| #endregion
| | >|
| | >| #region EventArgs and Delegates
| | >|
| | >| public class OnReadOnlyChangedEventArgs :
| | >| EventArgs
| | >| {
| | >| private bool mReadOnly;
| | >|
| | >| public OnReadOnlyChangedEventArgs
| | >| (bool ReadOnly)
| | >| {
| | >| mReadOnly = ReadOnly;
| | >| }
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| }
| | >| }
| | >| public delegate void
| | >| OnReadOnlyChangedDelegate(object sender,
| | >| OnReadOnlyChangedEventArgs e);
| | >|
| | >| #endregion
| | >|
| | >| #region Constructor
| | >|
| | >| public LockableDateTimePicker()
| | >| {
| | >| // This call is required by the
| | >| Windows.Forms Form Designer.
| | >| InitializeComponent();
| | >|
| | >| mBackColor =
| | >| base.CalendarMonthBackground;
| | >| mLockedColor =
| | >| base.CalendarMonthBackground;
| | >|
| | >| //Set defaults for this control
| | >| base.Format =
| | >| DateTimePickerFormat.Short;
| | >|
| | >| //Make sure that our date backup
| | >| is populated
| | >| mDateTime = base.Value;
| | >| mChecked = base.Checked;
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Properties
| | >|
| | >| [DesignerSerializationVisibility
| | >| (DesignerSerializationVisibility.Visible)]
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| set
| | >| {
| | >| if(value)
| | >| {
| | >|
| | >| base.CalendarMonthBackground = mLockedColor;
| | >| }
| | >| else
| | >| {
| | >|
| | >| base.CalendarMonthBackground = mBackColor;
| | >| }
| | >|
| | >| mReadOnly = value;
| | >| if(OnReadOnlyChanged !=
| | >| null)
| | >| {
| | >| OnReadOnlyChanged
| | >| (this, new OnReadOnlyChangedEventArgs(value));
| | >| }
| | >| }
| | >| }
| | >|
| | >| [DesignerSerializationVisibility
| | >| (DesignerSerializationVisibility.Visible)]
| | >| public Color LockedColor
| | >| {
| | >| get
| | >| {
| | >| return mLockedColor;
| | >| }
| | >| set
| | >| {
| | >| mLockedColor = value;
| | >| }
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Public Overridden Properties
| | >| public override Color BackColor
| | >| {
| | >| get
| | >| {
| | >| return base.BackColor;
| | >| }
| | >| set
| | >| {
| | >| mBackColor = value;
| | >| if(!mReadOnly)
| | >| {
| | >| base.BackColor =
| | >| value;
| | >| }
| | >| }
| | >| }
| | >| public new OptionalDateTime Value
| | >| {
| | >| set
| | >| {
| | >| if(value.GetValue() == "")
| | >| {
| | >| base.Checked =
| | >| false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =
| | >| DateTime.Parse(value.GetValue());
| | >| }
| | >|
| | >| }
| | >| get
| | >| {
| | >| if(base.Checked)
| | >| {
| | >| return new
| | >| OptionalDateTime(base.Value);
| | >| }
| | >| else
| | >| {
| | >| return new
| | >| OptionalDateTime();
| | >| }
| | >| }
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Overridden Events
| | >|
| | >| protected override void OnValueChanged
| | >| (EventArgs eventargs)
| | >| {
| | >| base.OnValueChanged (eventargs);
| | >|
| | >| if(mReadOnly)
| | >| {
| | >| //We need to set the
| | >| value of the control back to
| | >| //the stored value, since
| | >| it is read only
| | >| if(base.Value !=
| | >| mDateTime)
| | >| {
| | >| base.Value =
| | >| mDateTime;
| | >| }
| | >| if(base.Checked !=
| | >| mChecked)
| | >| {
| | >| base.Checked =
| | >| mChecked;
| | >| }
| | >| }
| | >| else
| | >| {
| | >| //Store the value for
| | >| when it's read only
| | >| mDateTime = base.Value;
| | >| mChecked = base.Checked;
| | >| }
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Public Methods
| | >| public void Initialise(OptionalDateTime
| | >| Value)
| | >| {
| | >| //Temporarily set the control to
| | >| not ReadOnly.
| | >| bool mTempReadOnly = mReadOnly;
| | >| if(mReadOnly)
| | >| {
| | >| mReadOnly = false;
| | >| }
| | >|
| | >| if(Value.GetValue() == "")
| | >| {
| | >| base.Checked = false;
| | >| mChecked = false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =
| | >| DateTime.Parse(Value.GetValue());
| | >| base.Checked = true;
| | >| mDateTime = base.Value;
| | >| mChecked = true;
| | >| }
| | >|
| | >| //Make sure the ReadOnly value is
| | >| returned to normal
| | >| mReadOnly = mTempReadOnly;
| | >| }
| | >| public void Initialise(DateTime Value)
| | >| {
| | >| Initialise(new OptionalDateTime
| | >| (Value));
| | >| }
| | >| public void Initialise()
| | >| {
| | >| Initialise(new OptionalDateTime
| | >| ());
| | >| }
| | >| #endregion
| | >| }
| | >| }
| | >|
| | >| ##############OptionalDateTime Source##########
| | >|
| | >| [Serializable()]
| | >| public class OptionalDateTime
| | >| {
| | >| #region Enum
| | >| /// <summary>
| | >| /// Formats available - extend as
| | >| required, but remember to update <see
| | cref="GetValue"/>.
| | >| /// </summary>
| | >| public enum enumDateTimeFormat
| | >| {
| | >| /// <summary>
| | >| /// LongDateFormat
| | >| /// </summary>
| | >| LongDateFormat,
| | >| /// <summary>
| | >| /// LongTimeFormat
| | >| /// </summary>
| | >| LongTimeFormat,
| | >| /// <summary>
| | >| /// ShortDateFormat
| | >| /// </summary>
| | >| ShortDateFormat,
| | >| /// <summary>
| | >| /// ShortTimeFormat
| | >| /// </summary>
| | >| ShortTimeFormat
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >| private DateTime mDate;
| | >| private bool mIsNull;
| | >| #endregion
| | >|
| | >| #region Constructor
| | >| /// <summary>
| | >| /// Constructor - initialises a null
| | >| OptionalDateTime
| | >| /// </summary>
| | >| public OptionalDateTime()
| | >| {
| | >| mIsNull = true;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTime to contain the value of a string.
| | >| /// If the string is not a valid
| | >| DateTime, the object is set to contain a null date.
| | >| /// </summary>
| | >| /// <param name="value">A string
| | >| representing a valid date.</param>
| | >| public OptionalDateTime(string value)
| | >| {
| | >| SetValue(value);
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTime to contain the value of a DateTime.
| | >| /// </summary>
| | >| /// <param name="value">A DateTime value
| | >| type.</param>
| | >| public OptionalDateTime(DateTime value)
| | >| {
| | >| SetValue(value);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Methods
| | >| /// <summary>
| | >| /// Set the value of the object to equal
| | >| that of a DateTime.
| | >| /// </summary>
| | >| /// <param name="value">A
| | >| DateTime.</param>
| | >| public void SetValue(DateTime value)
| | >| {
| | >| mDate = value;
| | >| mIsNull = false;
| | >| }
| | >| /// <summary>
| | >| /// Set the value of the object to equal
| | >| that of a string. If the string is not a valid
| | >| /// DateTime, the object is set to
| | >| contain a null date.
| | >| /// </summary>
| | >| /// <param name="value">A string
| | >| representing a valid date.</param>
| | >| public void SetValue(string value)
| | >| {
| | >| if(value == null || value == "")
| | >| {
| | >| mIsNull = true;
| | >| }
| | >| else
| | >| {
| | >| try
| | >| {
| | >| mDate =
| | >| DateTime.Parse(value);
| | >| mIsNull = false;
| | >| }
| | >| catch
| | >| {
| | >| throw new
| | >| ArgumentException("The string entered cannot be
| | converted
| | >| to a DateTime", "value");
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a
| | >| string with optional formatting.
| | >| /// </summary>
| | >| /// <param name="Format">The format to
| | >| return.</param>
| | >| /// <returns>A string containing the
| | >| correctly formatted date.</returns>
| | >| public string GetValue(enumDateTimeFormat
| | >| Format)
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| return "";
| | >| }
| | >| else
| | >| {
| | >| switch(Format)
| | >| {
| | >| case
| | >| enumDateTimeFormat.LongDateFormat:
| | >| return
| | >| mDate.ToLongDateString();
| | >| case
| | >| enumDateTimeFormat.LongTimeFormat:
| | >| return
| | >| mDate.ToLongTimeString();
| | >| case
| | >| enumDateTimeFormat.ShortDateFormat:
| | >| return
| | >| mDate.ToShortDateString();
| | >| case
| | >| enumDateTimeFormat.ShortTimeFormat:
| | >| return
| | >| mDate.ToShortTimeString();
| | >| default:
| | >| throw new
| | >| UnhandledDateFormatException(Format);
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a
| | >| ShortDateString.
| | >| /// </summary>
| | >| /// <returns></returns>
| | >| public string GetValue()
| | >| {
| | >| return GetValue
| | >| (enumDateTimeFormat.ShortDateFormat);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Override Methods
| | >| /// <summary>
| | >| /// Passes a string containing the date
| | >| in <see cref="enumDateTimeFormat.ShortDateFormat"/>.
| | >| /// </summary>
| | >| /// <returns>The date returned. Passes an
| | >| empty string for blank (null) dates.</returns>
| | >| public override string ToString()
| | >| {
| | >| return GetValue();
| | >| }
| | >| #endregion
| | >|
| | >| #region Properties
| | >| /// <summary>
| | >| /// Returns the date of the
| | >| OptionalDateTime as a DateTime type. Raises the
| | >| /// <see
| | >| cref="OptionalDateTimeIsNullException"/> if the
| | >| OptionalDateTime is
| | >| /// blank (null). Check the <see
| | >| cref="IsNull"/> property before calling this
| | >| /// method to avoid the exception.
| | >| /// </summary>
| | >| public DateTime GetDateTime
| | >| {
| | >| get
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| throw new
| | >| OptionalDateTimeIsNullException();
| | >| }
| | >| return mDate;
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Gets a boolean value indicating
| | >| whether the OptionalDateTime is blank (null).
| | >| /// </summary>
| | >| public bool IsNull
| | >| {
| | >| get
| | >| {
| | >| return mIsNull;
| | >| }
| | >| }
| | >| #endregion
| | >| }
| | >|
| | >| thanks in advance
| | >|
| | >
| | >.
| | >
| |
|

Nov 15 '05 #5


Hi Guy,

Sorry for letting you waiting so long time.
In this time, I did a lot of research into DateTimePicker control and
wanted to find a workaround for you.
Here, I provide you 2 ways of workaround:
First: override its OnCloseUp method and reset its value to its original
value. But this is not enough, when you open the datetimepicker, you can
use keyboard arrow to navigate the selection, and the value displayed will
also change in the textbox( For the moment, we call it textbox). I think we
should not let this happen, the value should stay the same. But just reset
value in the OnValueChanged method seems work well on keyboard navigation,
but will again change the value when closing the calendar.(It seems that
the OnCloseUp abated). So I hooked into this control, and filter its
MCN_SELCHANGE notification in WM_NOTIFY message.

using System.Runtime .InteropServices ;
public bool readonlyval=false;
private DateTime oldval;

oldval=this.Value; // in this control's constructor

protected override void OnCloseUp(EventArgs eventargs)
{
if(readonlyval==true)
{
this.Value =oldval;
}
oldval=this.Value ;
base.OnCloseUp (eventargs);
}

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=MCN_FIRST + 1;
private int WM_NOTIFY=0x004E;

[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(this.oldval==true)
{
if(m.Msg==WM_NOTIFY)
{
if(m.HWnd==this.Handle)
{
NMHDR nm1=(NMHDR)Marshal.PtrToStructure(m.LParam,typeof( NMHDR));
if(nm1.code==MCN_SELCHANGE)
{
return;
}
}
}
base.WndProc (ref m);
}
}

I use Spy++ to find that the DateTimePicker control will receive WM_NOTIFY
message with MCN_SELCHANGE code when selection changes.
All the const value MCN_SELCHANGE, MCN_FIRST can be found in the C:\Program
Files\Microsoft Visual Studio\VC98\Include directory *.h files.

It works well on my machine. If you have any question, please feel free to
tell me.
I will reply the second way of workaround in another reply post.

Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Content-Class: urn:content-classes:message
| From: "guy" <gu*@hcs-ltd.co.uk>
| Sender: "guy" <gu*@hcs-ltd.co.uk>
| References: <08****************************@phx.gbl>
<6i**************@cpmsftngxa06.phx.gbl>
| Subject: RE: bug using Application.EnableVisualStyles() with
datetimepicker control
| Date: Tue, 28 Oct 2003 01:26:56 -0800
| Lines: 601
| Message-ID: <08****************************@phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Thread-Index: AcOdNaFMO+yabmhBTea+z5L0ii9kXg==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:194627
| NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Ok Jeffrey, ill wait for your reply
|
|
|
| >-----Original Message-----
| >
| >Hi Guy,
| >
| >It is an already known issue.
| >I will do some research on this to find some workaround
| for you.
| >Thanks for you understanding.
| >
| >Best regards,
| >Jeffrey Tan
| >Microsoft Online Partner Support
| >Get Secure! - www.microsoft.com/security
| >This posting is provided "as is" with no warranties and
| confers no rights.
| >
| >--------------------
| >| Content-Class: urn:content-classes:message
| >| From: "Guy" <gu*@hcs-ltd.co.uk>
| >| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| >| Subject: bug using Application.EnableVisualStyles()
| with datetimepicker
| >control
| >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| >| Lines: 540
| >| Message-ID: <08****************************@phx.gbl>
| >| MIME-Version: 1.0
| >| Content-Type: text/plain;
| >| charset="iso-8859-1"
| >| Content-Transfer-Encoding: 7bit
| >| X-Newsreader: Microsoft CDO for Windows 2000
| >| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| >| X-MimeOLE: Produced By Microsoft MimeOLE
| V5.50.4910.0300
| >| Newsgroups: microsoft.public.dotnet.languages.csharp
| >| Path: cpmsftngxa06.phx.gbl
| >| Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:193774
| >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| >| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| >|
| >| I have extended the datetimepicker control to
| incorporate
| >| a ReadOnly property.
| >| I have used the new keyword to implement my own
| version
| >| of the value property, so that if readonly == true
| then
| >| it will not set the value of the control and will
| leave
| >| the checked status of the checkbox to false when a
| user
| >| selects a new date.
| >|
| >| this works fine when using the control on a win2k
| machine
| >| but if we use it on a win XP box and call
| >| Application.EnableVisualStyles() then it seems to
| ignore
| >| my code and check the checkbox and set the value. this
| is
| >| extremely buggy behaviour! and also the value property
| >| gets called twice (only once on a win2k box).
| >|
| >| i have also noticed behaviour changes in the
| >| label.textalignment property when using XP Visual
| styles
| >| aswell. Below is my implementation of the extended
| >| datetimepicker and also the new data type
| >| (OptionalDateTime) that is used for the value
| property...
| >|
| >| #####LockableDateTimePicker Source###########
| >|
| >| using System;
| >| using System.Collections;
| >| using System.ComponentModel;
| >| using System.Drawing;
| >| using System.Data;
| >| using System.Windows.Forms;
| >| using HCS.DataTypes;
| >|
| >| namespace HCS.Generic.UI.Controls
| >| {
| >| /// <summary>
| >| /// LockableDateTimePicker is for selecting
| >| dates. It manipulates the OptionalDateTime
| >| /// class to allow null dates to be handled.
| >| /// </summary>
| >| public class LockableDateTimePicker :
| >| DateTimePicker
| >| {
| >| #region Clean Up Code
| >|
| >| /// <summary>
| >| /// Clean up any resources being used.
| >| /// </summary>
| >| protected override void Dispose( bool
| >| disposing )
| >| {
| >| if( disposing )
| >| {
| >| if(components != null)
| >| {
| >| components.Dispose
| >| ();
| >| }
| >| }
| >| base.Dispose( disposing );
| >| }
| >|
| >| #endregion
| >|
| >| #region Component Designer generated code
| >| /// <summary>
| >| /// Required method for Designer support -
| >| do not modify
| >| /// the contents of this method with the
| >| code editor.
| >| /// </summary>
| >| private void InitializeComponent()
| >| {
| >| components = new
| >| System.ComponentModel.Container();
| >| }
| >| #endregion
| >|
| >| #region Fields
| >|
| >| private System.ComponentModel.Container
| >| components = null;
| >| private bool mReadOnly;
| >| private DateTime mDateTime;
| >| private Color mBackColor;
| >| private Color mLockedColor;
| >| private bool mChecked;
| >|
| >| #endregion
| >|
| >| #region Events
| >|
| >| public event OnReadOnlyChangedDelegate
| >| OnReadOnlyChanged;
| >|
| >| #endregion
| >|
| >| #region EventArgs and Delegates
| >|
| >| public class OnReadOnlyChangedEventArgs :
| >| EventArgs
| >| {
| >| private bool mReadOnly;
| >|
| >| public OnReadOnlyChangedEventArgs
| >| (bool ReadOnly)
| >| {
| >| mReadOnly = ReadOnly;
| >| }
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| }
| >| }
| >| public delegate void
| >| OnReadOnlyChangedDelegate(object sender,
| >| OnReadOnlyChangedEventArgs e);
| >|
| >| #endregion
| >|
| >| #region Constructor
| >|
| >| public LockableDateTimePicker()
| >| {
| >| // This call is required by the
| >| Windows.Forms Form Designer.
| >| InitializeComponent();
| >|
| >| mBackColor =
| >| base.CalendarMonthBackground;
| >| mLockedColor =
| >| base.CalendarMonthBackground;
| >|
| >| //Set defaults for this control
| >| base.Format =
| >| DateTimePickerFormat.Short;
| >|
| >| //Make sure that our date backup
| >| is populated
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >|
| >| #endregion
| >|
| >| #region Properties
| >|
| >| [DesignerSerializationVisibility
| >| (DesignerSerializationVisibility.Visible)]
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| set
| >| {
| >| if(value)
| >| {
| >|
| >| base.CalendarMonthBackground = mLockedColor;
| >| }
| >| else
| >| {
| >|
| >| base.CalendarMonthBackground = mBackColor;
| >| }
| >|
| >| mReadOnly = value;
| >| if(OnReadOnlyChanged !=
| >| null)
| >| {
| >| OnReadOnlyChanged
| >| (this, new OnReadOnlyChangedEventArgs(value));
| >| }
| >| }
| >| }
| >|
| >| [DesignerSerializationVisibility
| >| (DesignerSerializationVisibility.Visible)]
| >| public Color LockedColor
| >| {
| >| get
| >| {
| >| return mLockedColor;
| >| }
| >| set
| >| {
| >| mLockedColor = value;
| >| }
| >| }
| >|
| >| #endregion
| >|
| >| #region Public Overridden Properties
| >| public override Color BackColor
| >| {
| >| get
| >| {
| >| return base.BackColor;
| >| }
| >| set
| >| {
| >| mBackColor = value;
| >| if(!mReadOnly)
| >| {
| >| base.BackColor =
| >| value;
| >| }
| >| }
| >| }
| >| public new OptionalDateTime Value
| >| {
| >| set
| >| {
| >| if(value.GetValue() == "")
| >| {
| >| base.Checked =
| >| false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse(value.GetValue());
| >| }
| >|
| >| }
| >| get
| >| {
| >| if(base.Checked)
| >| {
| >| return new
| >| OptionalDateTime(base.Value);
| >| }
| >| else
| >| {
| >| return new
| >| OptionalDateTime();
| >| }
| >| }
| >| }
| >| #endregion
| >|
| >| #region Public Overridden Events
| >|
| >| protected override void OnValueChanged
| >| (EventArgs eventargs)
| >| {
| >| base.OnValueChanged (eventargs);
| >|
| >| if(mReadOnly)
| >| {
| >| //We need to set the
| >| value of the control back to
| >| //the stored value, since
| >| it is read only
| >| if(base.Value !=
| >| mDateTime)
| >| {
| >| base.Value =
| >| mDateTime;
| >| }
| >| if(base.Checked !=
| >| mChecked)
| >| {
| >| base.Checked =
| >| mChecked;
| >| }
| >| }
| >| else
| >| {
| >| //Store the value for
| >| when it's read only
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >| }
| >|
| >| #endregion
| >|
| >| #region Public Methods
| >| public void Initialise(OptionalDateTime
| >| Value)
| >| {
| >| //Temporarily set the control to
| >| not ReadOnly.
| >| bool mTempReadOnly = mReadOnly;
| >| if(mReadOnly)
| >| {
| >| mReadOnly = false;
| >| }
| >|
| >| if(Value.GetValue() == "")
| >| {
| >| base.Checked = false;
| >| mChecked = false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse(Value.GetValue());
| >| base.Checked = true;
| >| mDateTime = base.Value;
| >| mChecked = true;
| >| }
| >|
| >| //Make sure the ReadOnly value is
| >| returned to normal
| >| mReadOnly = mTempReadOnly;
| >| }
| >| public void Initialise(DateTime Value)
| >| {
| >| Initialise(new OptionalDateTime
| >| (Value));
| >| }
| >| public void Initialise()
| >| {
| >| Initialise(new OptionalDateTime
| >| ());
| >| }
| >| #endregion
| >| }
| >| }
| >|
| >| ##############OptionalDateTime Source##########
| >|
| >| [Serializable()]
| >| public class OptionalDateTime
| >| {
| >| #region Enum
| >| /// <summary>
| >| /// Formats available - extend as
| >| required, but remember to update <see
| cref="GetValue"/>.
| >| /// </summary>
| >| public enum enumDateTimeFormat
| >| {
| >| /// <summary>
| >| /// LongDateFormat
| >| /// </summary>
| >| LongDateFormat,
| >| /// <summary>
| >| /// LongTimeFormat
| >| /// </summary>
| >| LongTimeFormat,
| >| /// <summary>
| >| /// ShortDateFormat
| >| /// </summary>
| >| ShortDateFormat,
| >| /// <summary>
| >| /// ShortTimeFormat
| >| /// </summary>
| >| ShortTimeFormat
| >| }
| >| #endregion
| >|
| >| #region Fields
| >| private DateTime mDate;
| >| private bool mIsNull;
| >| #endregion
| >|
| >| #region Constructor
| >| /// <summary>
| >| /// Constructor - initialises a null
| >| OptionalDateTime
| >| /// </summary>
| >| public OptionalDateTime()
| >| {
| >| mIsNull = true;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTime to contain the value of a string.
| >| /// If the string is not a valid
| >| DateTime, the object is set to contain a null date.
| >| /// </summary>
| >| /// <param name="value">A string
| >| representing a valid date.</param>
| >| public OptionalDateTime(string value)
| >| {
| >| SetValue(value);
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTime to contain the value of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A DateTime value
| >| type.</param>
| >| public OptionalDateTime(DateTime value)
| >| {
| >| SetValue(value);
| >| }
| >| #endregion
| >|
| >| #region Public Methods
| >| /// <summary>
| >| /// Set the value of the object to equal
| >| that of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A
| >| DateTime.</param>
| >| public void SetValue(DateTime value)
| >| {
| >| mDate = value;
| >| mIsNull = false;
| >| }
| >| /// <summary>
| >| /// Set the value of the object to equal
| >| that of a string. If the string is not a valid
| >| /// DateTime, the object is set to
| >| contain a null date.
| >| /// </summary>
| >| /// <param name="value">A string
| >| representing a valid date.</param>
| >| public void SetValue(string value)
| >| {
| >| if(value == null || value == "")
| >| {
| >| mIsNull = true;
| >| }
| >| else
| >| {
| >| try
| >| {
| >| mDate =
| >| DateTime.Parse(value);
| >| mIsNull = false;
| >| }
| >| catch
| >| {
| >| throw new
| >| ArgumentException("The string entered cannot be
| converted
| >| to a DateTime", "value");
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| string with optional formatting.
| >| /// </summary>
| >| /// <param name="Format">The format to
| >| return.</param>
| >| /// <returns>A string containing the
| >| correctly formatted date.</returns>
| >| public string GetValue(enumDateTimeFormat
| >| Format)
| >| {
| >| if(mIsNull)
| >| {
| >| return "";
| >| }
| >| else
| >| {
| >| switch(Format)
| >| {
| >| case
| >| enumDateTimeFormat.LongDateFormat:
| >| return
| >| mDate.ToLongDateString();
| >| case
| >| enumDateTimeFormat.LongTimeFormat:
| >| return
| >| mDate.ToLongTimeString();
| >| case
| >| enumDateTimeFormat.ShortDateFormat:
| >| return
| >| mDate.ToShortDateString();
| >| case
| >| enumDateTimeFormat.ShortTimeFormat:
| >| return
| >| mDate.ToShortTimeString();
| >| default:
| >| throw new
| >| UnhandledDateFormatException(Format);
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| ShortDateString.
| >| /// </summary>
| >| /// <returns></returns>
| >| public string GetValue()
| >| {
| >| return GetValue
| >| (enumDateTimeFormat.ShortDateFormat);
| >| }
| >| #endregion
| >|
| >| #region Public Override Methods
| >| /// <summary>
| >| /// Passes a string containing the date
| >| in <see cref="enumDateTimeFormat.ShortDateFormat"/>.
| >| /// </summary>
| >| /// <returns>The date returned. Passes an
| >| empty string for blank (null) dates.</returns>
| >| public override string ToString()
| >| {
| >| return GetValue();
| >| }
| >| #endregion
| >|
| >| #region Properties
| >| /// <summary>
| >| /// Returns the date of the
| >| OptionalDateTime as a DateTime type. Raises the
| >| /// <see
| >| cref="OptionalDateTimeIsNullException"/> if the
| >| OptionalDateTime is
| >| /// blank (null). Check the <see
| >| cref="IsNull"/> property before calling this
| >| /// method to avoid the exception.
| >| /// </summary>
| >| public DateTime GetDateTime
| >| {
| >| get
| >| {
| >| if(mIsNull)
| >| {
| >| throw new
| >| OptionalDateTimeIsNullException();
| >| }
| >| return mDate;
| >| }
| >| }
| >| /// <summary>
| >| /// Gets a boolean value indicating
| >| whether the OptionalDateTime is blank (null).
| >| /// </summary>
| >| public bool IsNull
| >| {
| >| get
| >| {
| >| return mIsNull;
| >| }
| >| }
| >| #endregion
| >| }
| >|
| >| thanks in advance
| >|
| >
| >.
| >
|

Nov 15 '05 #6

Hi Guy,

Sorry for letting you waiting so long time.
In this time, I did a lot of research into DateTimePicker control and
wanted to find a workaround for you.
Here, I provide you 2 ways of workaround:
First: override its OnCloseUp method and reset its value to its original
value. But this is not enough, when you open the datetimepicker, you can
use keyboard arrow to navigate the selection, and the value displayed will
also change in the textbox( For the moment, we call it textbox). I think we
should not let this happen, the value should stay the same. But just reset
value in the OnValueChanged method seems work well on keyboard navigation,
but will again change the value when closing the calendar.(It seems that
the OnCloseUp abated). So I hooked into this control, and filter its
MCN_SELCHANGE notification in WM_NOTIFY message.

using System.Runtime .InteropServices ;
public bool readonlyval=false;
private DateTime oldval;

oldval=this.Value; // in this control's constructor

protected override void OnCloseUp(EventArgs eventargs)
{
if(readonlyval==true)
{
this.Value =oldval;
}
oldval=this.Value ;
base.OnCloseUp (eventargs);
}

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=MCN_FIRST + 1;
private int WM_NOTIFY=0x004E;

[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(this.readonlyval==true)
{
if(m.Msg==WM_NOTIFY)
{
if(m.HWnd==this.Handle)
{
NMHDR nm1=(NMHDR)Marshal.PtrToStructure(m.LParam,typeof( NMHDR));
if(nm1.code==MCN_SELCHANGE)
{
return;
}
}
}
base.WndProc (ref m);
}
}

I use Spy++ to find that the DateTimePicker control will receive WM_NOTIFY
message with MCN_SELCHANGE code when selection changes.
All the const value MCN_SELCHANGE, MCN_FIRST can be found in the C:\Program
Files\Microsoft Visual Studio\VC98\Include directory *.h files.

It works well on my machine. If you have any question, please feel free to
tell me.
I will reply the second way of workaround in another reply post.

Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Content-Class: urn:content-classes:message
| From: "guy" <gu*@hcs-ltd.co.uk>
| Sender: "guy" <gu*@hcs-ltd.co.uk>
| References: <08****************************@phx.gbl>
<6i**************@cpmsftngxa06.phx.gbl>
| Subject: RE: bug using Application.EnableVisualStyles() with
datetimepicker control
| Date: Tue, 28 Oct 2003 01:26:56 -0800
| Lines: 601
| Message-ID: <08****************************@phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Thread-Index: AcOdNaFMO+yabmhBTea+z5L0ii9kXg==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:194627
| NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Ok Jeffrey, ill wait for your reply
|
|
|
| >-----Original Message-----
| >
| >Hi Guy,
| >
| >It is an already known issue.
| >I will do some research on this to find some workaround
| for you.
| >Thanks for you understanding.
| >
| >Best regards,
| >Jeffrey Tan
| >Microsoft Online Partner Support
| >Get Secure! - www.microsoft.com/security
| >This posting is provided "as is" with no warranties and
| confers no rights.
| >
| >--------------------
| >| Content-Class: urn:content-classes:message
| >| From: "Guy" <gu*@hcs-ltd.co.uk>
| >| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| >| Subject: bug using Application.EnableVisualStyles()
| with datetimepicker
| >control
| >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| >| Lines: 540
| >| Message-ID: <08****************************@phx.gbl>
| >| MIME-Version: 1.0
| >| Content-Type: text/plain;
| >| charset="iso-8859-1"
| >| Content-Transfer-Encoding: 7bit
| >| X-Newsreader: Microsoft CDO for Windows 2000
| >| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| >| X-MimeOLE: Produced By Microsoft MimeOLE
| V5.50.4910.0300
| >| Newsgroups: microsoft.public.dotnet.languages.csharp
| >| Path: cpmsftngxa06.phx.gbl
| >| Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:193774
| >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| >| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| >|
| >| I have extended the datetimepicker control to
| incorporate
| >| a ReadOnly property.
| >| I have used the new keyword to implement my own
| version
| >| of the value property, so that if readonly == true
| then
| >| it will not set the value of the control and will
| leave
| >| the checked status of the checkbox to false when a
| user
| >| selects a new date.
| >|
| >| this works fine when using the control on a win2k
| machine
| >| but if we use it on a win XP box and call
| >| Application.EnableVisualStyles() then it seems to
| ignore
| >| my code and check the checkbox and set the value. this
| is
| >| extremely buggy behaviour! and also the value property
| >| gets called twice (only once on a win2k box).
| >|
| >| i have also noticed behaviour changes in the
| >| label.textalignment property when using XP Visual
| styles
| >| aswell. Below is my implementation of the extended
| >| datetimepicker and also the new data type
| >| (OptionalDateTime) that is used for the value
| property...
| >|
| >| #####LockableDateTimePicker Source###########
| >|
| >| using System;
| >| using System.Collections;
| >| using System.ComponentModel;
| >| using System.Drawing;
| >| using System.Data;
| >| using System.Windows.Forms;
| >| using HCS.DataTypes;
| >|
| >| namespace HCS.Generic.UI.Controls
| >| {
| >| /// <summary>
| >| /// LockableDateTimePicker is for selecting
| >| dates. It manipulates the OptionalDateTime
| >| /// class to allow null dates to be handled.
| >| /// </summary>
| >| public class LockableDateTimePicker :
| >| DateTimePicker
| >| {
| >| #region Clean Up Code
| >|
| >| /// <summary>
| >| /// Clean up any resources being used.
| >| /// </summary>
| >| protected override void Dispose( bool
| >| disposing )
| >| {
| >| if( disposing )
| >| {
| >| if(components != null)
| >| {
| >| components.Dispose
| >| ();
| >| }
| >| }
| >| base.Dispose( disposing );
| >| }
| >|
| >| #endregion
| >|
| >| #region Component Designer generated code
| >| /// <summary>
| >| /// Required method for Designer support -
| >| do not modify
| >| /// the contents of this method with the
| >| code editor.
| >| /// </summary>
| >| private void InitializeComponent()
| >| {
| >| components = new
| >| System.ComponentModel.Container();
| >| }
| >| #endregion
| >|
| >| #region Fields
| >|
| >| private System.ComponentModel.Container
| >| components = null;
| >| private bool mReadOnly;
| >| private DateTime mDateTime;
| >| private Color mBackColor;
| >| private Color mLockedColor;
| >| private bool mChecked;
| >|
| >| #endregion
| >|
| >| #region Events
| >|
| >| public event OnReadOnlyChangedDelegate
| >| OnReadOnlyChanged;
| >|
| >| #endregion
| >|
| >| #region EventArgs and Delegates
| >|
| >| public class OnReadOnlyChangedEventArgs :
| >| EventArgs
| >| {
| >| private bool mReadOnly;
| >|
| >| public OnReadOnlyChangedEventArgs
| >| (bool ReadOnly)
| >| {
| >| mReadOnly = ReadOnly;
| >| }
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| }
| >| }
| >| public delegate void
| >| OnReadOnlyChangedDelegate(object sender,
| >| OnReadOnlyChangedEventArgs e);
| >|
| >| #endregion
| >|
| >| #region Constructor
| >|
| >| public LockableDateTimePicker()
| >| {
| >| // This call is required by the
| >| Windows.Forms Form Designer.
| >| InitializeComponent();
| >|
| >| mBackColor =
| >| base.CalendarMonthBackground;
| >| mLockedColor =
| >| base.CalendarMonthBackground;
| >|
| >| //Set defaults for this control
| >| base.Format =
| >| DateTimePickerFormat.Short;
| >|
| >| //Make sure that our date backup
| >| is populated
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >|
| >| #endregion
| >|
| >| #region Properties
| >|
| >| [DesignerSerializationVisibility
| >| (DesignerSerializationVisibility.Visible)]
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| set
| >| {
| >| if(value)
| >| {
| >|
| >| base.CalendarMonthBackground = mLockedColor;
| >| }
| >| else
| >| {
| >|
| >| base.CalendarMonthBackground = mBackColor;
| >| }
| >|
| >| mReadOnly = value;
| >| if(OnReadOnlyChanged !=
| >| null)
| >| {
| >| OnReadOnlyChanged
| >| (this, new OnReadOnlyChangedEventArgs(value));
| >| }
| >| }
| >| }
| >|
| >| [DesignerSerializationVisibility
| >| (DesignerSerializationVisibility.Visible)]
| >| public Color LockedColor
| >| {
| >| get
| >| {
| >| return mLockedColor;
| >| }
| >| set
| >| {
| >| mLockedColor = value;
| >| }
| >| }
| >|
| >| #endregion
| >|
| >| #region Public Overridden Properties
| >| public override Color BackColor
| >| {
| >| get
| >| {
| >| return base.BackColor;
| >| }
| >| set
| >| {
| >| mBackColor = value;
| >| if(!mReadOnly)
| >| {
| >| base.BackColor =
| >| value;
| >| }
| >| }
| >| }
| >| public new OptionalDateTime Value
| >| {
| >| set
| >| {
| >| if(value.GetValue() == "")
| >| {
| >| base.Checked =
| >| false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse(value.GetValue());
| >| }
| >|
| >| }
| >| get
| >| {
| >| if(base.Checked)
| >| {
| >| return new
| >| OptionalDateTime(base.Value);
| >| }
| >| else
| >| {
| >| return new
| >| OptionalDateTime();
| >| }
| >| }
| >| }
| >| #endregion
| >|
| >| #region Public Overridden Events
| >|
| >| protected override void OnValueChanged
| >| (EventArgs eventargs)
| >| {
| >| base.OnValueChanged (eventargs);
| >|
| >| if(mReadOnly)
| >| {
| >| //We need to set the
| >| value of the control back to
| >| //the stored value, since
| >| it is read only
| >| if(base.Value !=
| >| mDateTime)
| >| {
| >| base.Value =
| >| mDateTime;
| >| }
| >| if(base.Checked !=
| >| mChecked)
| >| {
| >| base.Checked =
| >| mChecked;
| >| }
| >| }
| >| else
| >| {
| >| //Store the value for
| >| when it's read only
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >| }
| >|
| >| #endregion
| >|
| >| #region Public Methods
| >| public void Initialise(OptionalDateTime
| >| Value)
| >| {
| >| //Temporarily set the control to
| >| not ReadOnly.
| >| bool mTempReadOnly = mReadOnly;
| >| if(mReadOnly)
| >| {
| >| mReadOnly = false;
| >| }
| >|
| >| if(Value.GetValue() == "")
| >| {
| >| base.Checked = false;
| >| mChecked = false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse(Value.GetValue());
| >| base.Checked = true;
| >| mDateTime = base.Value;
| >| mChecked = true;
| >| }
| >|
| >| //Make sure the ReadOnly value is
| >| returned to normal
| >| mReadOnly = mTempReadOnly;
| >| }
| >| public void Initialise(DateTime Value)
| >| {
| >| Initialise(new OptionalDateTime
| >| (Value));
| >| }
| >| public void Initialise()
| >| {
| >| Initialise(new OptionalDateTime
| >| ());
| >| }
| >| #endregion
| >| }
| >| }
| >|
| >| ##############OptionalDateTime Source##########
| >|
| >| [Serializable()]
| >| public class OptionalDateTime
| >| {
| >| #region Enum
| >| /// <summary>
| >| /// Formats available - extend as
| >| required, but remember to update <see
| cref="GetValue"/>.
| >| /// </summary>
| >| public enum enumDateTimeFormat
| >| {
| >| /// <summary>
| >| /// LongDateFormat
| >| /// </summary>
| >| LongDateFormat,
| >| /// <summary>
| >| /// LongTimeFormat
| >| /// </summary>
| >| LongTimeFormat,
| >| /// <summary>
| >| /// ShortDateFormat
| >| /// </summary>
| >| ShortDateFormat,
| >| /// <summary>
| >| /// ShortTimeFormat
| >| /// </summary>
| >| ShortTimeFormat
| >| }
| >| #endregion
| >|
| >| #region Fields
| >| private DateTime mDate;
| >| private bool mIsNull;
| >| #endregion
| >|
| >| #region Constructor
| >| /// <summary>
| >| /// Constructor - initialises a null
| >| OptionalDateTime
| >| /// </summary>
| >| public OptionalDateTime()
| >| {
| >| mIsNull = true;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTime to contain the value of a string.
| >| /// If the string is not a valid
| >| DateTime, the object is set to contain a null date.
| >| /// </summary>
| >| /// <param name="value">A string
| >| representing a valid date.</param>
| >| public OptionalDateTime(string value)
| >| {
| >| SetValue(value);
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTime to contain the value of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A DateTime value
| >| type.</param>
| >| public OptionalDateTime(DateTime value)
| >| {
| >| SetValue(value);
| >| }
| >| #endregion
| >|
| >| #region Public Methods
| >| /// <summary>
| >| /// Set the value of the object to equal
| >| that of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A
| >| DateTime.</param>
| >| public void SetValue(DateTime value)
| >| {
| >| mDate = value;
| >| mIsNull = false;
| >| }
| >| /// <summary>
| >| /// Set the value of the object to equal
| >| that of a string. If the string is not a valid
| >| /// DateTime, the object is set to
| >| contain a null date.
| >| /// </summary>
| >| /// <param name="value">A string
| >| representing a valid date.</param>
| >| public void SetValue(string value)
| >| {
| >| if(value == null || value == "")
| >| {
| >| mIsNull = true;
| >| }
| >| else
| >| {
| >| try
| >| {
| >| mDate =
| >| DateTime.Parse(value);
| >| mIsNull = false;
| >| }
| >| catch
| >| {
| >| throw new
| >| ArgumentException("The string entered cannot be
| converted
| >| to a DateTime", "value");
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| string with optional formatting.
| >| /// </summary>
| >| /// <param name="Format">The format to
| >| return.</param>
| >| /// <returns>A string containing the
| >| correctly formatted date.</returns>
| >| public string GetValue(enumDateTimeFormat
| >| Format)
| >| {
| >| if(mIsNull)
| >| {
| >| return "";
| >| }
| >| else
| >| {
| >| switch(Format)
| >| {
| >| case
| >| enumDateTimeFormat.LongDateFormat:
| >| return
| >| mDate.ToLongDateString();
| >| case
| >| enumDateTimeFormat.LongTimeFormat:
| >| return
| >| mDate.ToLongTimeString();
| >| case
| >| enumDateTimeFormat.ShortDateFormat:
| >| return
| >| mDate.ToShortDateString();
| >| case
| >| enumDateTimeFormat.ShortTimeFormat:
| >| return
| >| mDate.ToShortTimeString();
| >| default:
| >| throw new
| >| UnhandledDateFormatException(Format);
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| ShortDateString.
| >| /// </summary>
| >| /// <returns></returns>
| >| public string GetValue()
| >| {
| >| return GetValue
| >| (enumDateTimeFormat.ShortDateFormat);
| >| }
| >| #endregion
| >|
| >| #region Public Override Methods
| >| /// <summary>
| >| /// Passes a string containing the date
| >| in <see cref="enumDateTimeFormat.ShortDateFormat"/>.
| >| /// </summary>
| >| /// <returns>The date returned. Passes an
| >| empty string for blank (null) dates.</returns>
| >| public override string ToString()
| >| {
| >| return GetValue();
| >| }
| >| #endregion
| >|
| >| #region Properties
| >| /// <summary>
| >| /// Returns the date of the
| >| OptionalDateTime as a DateTime type. Raises the
| >| /// <see
| >| cref="OptionalDateTimeIsNullException"/> if the
| >| OptionalDateTime is
| >| /// blank (null). Check the <see
| >| cref="IsNull"/> property before calling this
| >| /// method to avoid the exception.
| >| /// </summary>
| >| public DateTime GetDateTime
| >| {
| >| get
| >| {
| >| if(mIsNull)
| >| {
| >| throw new
| >| OptionalDateTimeIsNullException();
| >| }
| >| return mDate;
| >| }
| >| }
| >| /// <summary>
| >| /// Gets a boolean value indicating
| >| whether the OptionalDateTime is blank (null).
| >| /// </summary>
| >| public bool IsNull
| >| {
| >| get
| >| {
| >| return mIsNull;
| >| }
| >| }
| >| #endregion
| >| }
| >|
| >| thanks in advance
| >|
| >
| >.
| >
|

Nov 15 '05 #7

Hi Guy,

Second way:

I found that the normal mouse click selection of DateTimePicker will fires
3 WM_NOTIFY messages which code are NM_RELEASECAPTURE, MCN_SELCHANGE,
MCN_SELECT. And if I filter MCN_SELCHANGE, MCN_SELECT message, the calendar
will not change its value. But the problem is if I filter these 2 message,
the Calendar will not fade away when I click a item. It will stay the
there. So we must kill it. I use P/invoke the Win32 API DestroyWindow to
get this done.

using System.Runtime .InteropServices ;

public bool readonlyval=false;
private DateTime oldval;

oldval=this.Value ; // in control's constructor

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=MCN_FIRST + 1;
private const int MCN_SELECT=MCN_FIRST + 4;
private int WM_NOTIFY=0x004E;

[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hWnd1,IntPtr
hWnd2,string lpsz1,string lpsz2);

[DllImport("user32.dll")]
public static extern bool DestroyWindow(IntPtr hwnd);

[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(this.readonlyval==true)
{
if(m.Msg==WM_NOTIFY)
{
if(m.HWnd==this.Handle)
{
NMHDR nm1=(NMHDR)Marshal.PtrToStructure(m.LParam,typeof( NMHDR));
if(nm1.code==MCN_SELCHANGE)
{
return;
}
if(nm1.code ==MCN_SELECT)
{
IntPtr calendarhandle=FindWindowEx(IntPtr.Zero ,IntPtr.Zero
,"SysMonthCal32",String.Empty);
DestroyWindow(calendarhandle);
return;
}
}
}
}
base.WndProc (ref m);
}

Have a nice day!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Newsgroups: microsoft.public.dotnet.languages.csharp
| From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| Organization: Microsoft
| Date: Wed, 29 Oct 2003 03:46:45 GMT
| Subject: RE: bug using Application.EnableVisualStyles() with
datetimepicker control
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
|
|
| Hi Guy,
|
| Sorry for letting you waiting so long time.
| In this time, I did a lot of research into DateTimePicker control and
| wanted to find a workaround for you.
| Here, I provide you 2 ways of workaround:
| First: override its OnCloseUp method and reset its value to its original
| value. But this is not enough, when you open the datetimepicker, you can
| use keyboard arrow to navigate the selection, and the value displayed
will
| also change in the textbox( For the moment, we call it textbox). I think
we
| should not let this happen, the value should stay the same. But just
reset
| value in the OnValueChanged method seems work well on keyboard
navigation,
| but will again change the value when closing the calendar.(It seems that
| the OnCloseUp abated). So I hooked into this control, and filter its
| MCN_SELCHANGE notification in WM_NOTIFY message.
|
| using System.Runtime .InteropServices ;
| public bool readonlyval=false;
| private DateTime oldval;
|
| oldval=this.Value; // in this control's constructor
|
| protected override void OnCloseUp(EventArgs eventargs)
| {
| if(readonlyval==true)
| {
| this.Value =oldval;
| }
| oldval=this.Value ;
| base.OnCloseUp (eventargs);
| }
|
| private const int MCN_FIRST=-750;
| private const int MCN_SELCHANGE=MCN_FIRST + 1;
| private int WM_NOTIFY=0x004E;
|
| [StructLayout(LayoutKind.Sequential)]
| public struct NMHDR
| {
| public IntPtr hwndFrom;
| public int idfrom;
| public int code;
| }
|
| protected override void WndProc(ref Message m)
| {
| if(this.readonlyval==true)
| {
| if(m.Msg==WM_NOTIFY)
| {
| if(m.HWnd==this.Handle)
| {
| NMHDR nm1=(NMHDR)Marshal.PtrToStructure(m.LParam,typeof( NMHDR));
| if(nm1.code==MCN_SELCHANGE)
| {
| return;
| }
| }
| }
| base.WndProc (ref m);
| }
| }
|
| I use Spy++ to find that the DateTimePicker control will receive
WM_NOTIFY
| message with MCN_SELCHANGE code when selection changes.
| All the const value MCN_SELCHANGE, MCN_FIRST can be found in the
C:\Program
| Files\Microsoft Visual Studio\VC98\Include directory *.h files.
|
| It works well on my machine. If you have any question, please feel free
to
| tell me.
| I will reply the second way of workaround in another reply post.
|
| Jeffrey Tan
| Microsoft Online Partner Support
| Get Secure! - www.microsoft.com/security
| This posting is provided "as is" with no warranties and confers no rights.
|
| --------------------
| | Content-Class: urn:content-classes:message
| | From: "guy" <gu*@hcs-ltd.co.uk>
| | Sender: "guy" <gu*@hcs-ltd.co.uk>
| | References: <08****************************@phx.gbl>
| <6i**************@cpmsftngxa06.phx.gbl>
| | Subject: RE: bug using Application.EnableVisualStyles() with
| datetimepicker control
| | Date: Tue, 28 Oct 2003 01:26:56 -0800
| | Lines: 601
| | Message-ID: <08****************************@phx.gbl>
| | MIME-Version: 1.0
| | Content-Type: text/plain;
| | charset="iso-8859-1"
| | Content-Transfer-Encoding: 7bit
| | X-Newsreader: Microsoft CDO for Windows 2000
| | Thread-Index: AcOdNaFMO+yabmhBTea+z5L0ii9kXg==
| | X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| | Newsgroups: microsoft.public.dotnet.languages.csharp
| | Path: cpmsftngxa06.phx.gbl
| | Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.languages.csharp:194627
| | NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| |
| | Ok Jeffrey, ill wait for your reply
| |
| |
| |
| | >-----Original Message-----
| | >
| | >Hi Guy,
| | >
| | >It is an already known issue.
| | >I will do some research on this to find some workaround
| | for you.
| | >Thanks for you understanding.
| | >
| | >Best regards,
| | >Jeffrey Tan
| | >Microsoft Online Partner Support
| | >Get Secure! - www.microsoft.com/security
| | >This posting is provided "as is" with no warranties and
| | confers no rights.
| | >
| | >--------------------
| | >| Content-Class: urn:content-classes:message
| | >| From: "Guy" <gu*@hcs-ltd.co.uk>
| | >| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| | >| Subject: bug using Application.EnableVisualStyles()
| | with datetimepicker
| | >control
| | >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| | >| Lines: 540
| | >| Message-ID: <08****************************@phx.gbl>
| | >| MIME-Version: 1.0
| | >| Content-Type: text/plain;
| | >| charset="iso-8859-1"
| | >| Content-Transfer-Encoding: 7bit
| | >| X-Newsreader: Microsoft CDO for Windows 2000
| | >| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| | >| X-MimeOLE: Produced By Microsoft MimeOLE
| | V5.50.4910.0300
| | >| Newsgroups: microsoft.public.dotnet.languages.csharp
| | >| Path: cpmsftngxa06.phx.gbl
| | >| Xref: cpmsftngxa06.phx.gbl
| | microsoft.public.dotnet.languages.csharp:193774
| | >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| | >| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| | >|
| | >| I have extended the datetimepicker control to
| | incorporate
| | >| a ReadOnly property.
| | >| I have used the new keyword to implement my own
| | version
| | >| of the value property, so that if readonly == true
| | then
| | >| it will not set the value of the control and will
| | leave
| | >| the checked status of the checkbox to false when a
| | user
| | >| selects a new date.
| | >|
| | >| this works fine when using the control on a win2k
| | machine
| | >| but if we use it on a win XP box and call
| | >| Application.EnableVisualStyles() then it seems to
| | ignore
| | >| my code and check the checkbox and set the value. this
| | is
| | >| extremely buggy behaviour! and also the value property
| | >| gets called twice (only once on a win2k box).
| | >|
| | >| i have also noticed behaviour changes in the
| | >| label.textalignment property when using XP Visual
| | styles
| | >| aswell. Below is my implementation of the extended
| | >| datetimepicker and also the new data type
| | >| (OptionalDateTime) that is used for the value
| | property...
| | >|
| | >| #####LockableDateTimePicker Source###########
| | >|
| | >| using System;
| | >| using System.Collections;
| | >| using System.ComponentModel;
| | >| using System.Drawing;
| | >| using System.Data;
| | >| using System.Windows.Forms;
| | >| using HCS.DataTypes;
| | >|
| | >| namespace HCS.Generic.UI.Controls
| | >| {
| | >| /// <summary>
| | >| /// LockableDateTimePicker is for selecting
| | >| dates. It manipulates the OptionalDateTime
| | >| /// class to allow null dates to be handled.
| | >| /// </summary>
| | >| public class LockableDateTimePicker :
| | >| DateTimePicker
| | >| {
| | >| #region Clean Up Code
| | >|
| | >| /// <summary>
| | >| /// Clean up any resources being used.
| | >| /// </summary>
| | >| protected override void Dispose( bool
| | >| disposing )
| | >| {
| | >| if( disposing )
| | >| {
| | >| if(components != null)
| | >| {
| | >| components.Dispose
| | >| ();
| | >| }
| | >| }
| | >| base.Dispose( disposing );
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Component Designer generated code
| | >| /// <summary>
| | >| /// Required method for Designer support -
| | >| do not modify
| | >| /// the contents of this method with the
| | >| code editor.
| | >| /// </summary>
| | >| private void InitializeComponent()
| | >| {
| | >| components = new
| | >| System.ComponentModel.Container();
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >|
| | >| private System.ComponentModel.Container
| | >| components = null;
| | >| private bool mReadOnly;
| | >| private DateTime mDateTime;
| | >| private Color mBackColor;
| | >| private Color mLockedColor;
| | >| private bool mChecked;
| | >|
| | >| #endregion
| | >|
| | >| #region Events
| | >|
| | >| public event OnReadOnlyChangedDelegate
| | >| OnReadOnlyChanged;
| | >|
| | >| #endregion
| | >|
| | >| #region EventArgs and Delegates
| | >|
| | >| public class OnReadOnlyChangedEventArgs :
| | >| EventArgs
| | >| {
| | >| private bool mReadOnly;
| | >|
| | >| public OnReadOnlyChangedEventArgs
| | >| (bool ReadOnly)
| | >| {
| | >| mReadOnly = ReadOnly;
| | >| }
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| }
| | >| }
| | >| public delegate void
| | >| OnReadOnlyChangedDelegate(object sender,
| | >| OnReadOnlyChangedEventArgs e);
| | >|
| | >| #endregion
| | >|
| | >| #region Constructor
| | >|
| | >| public LockableDateTimePicker()
| | >| {
| | >| // This call is required by the
| | >| Windows.Forms Form Designer.
| | >| InitializeComponent();
| | >|
| | >| mBackColor =
| | >| base.CalendarMonthBackground;
| | >| mLockedColor =
| | >| base.CalendarMonthBackground;
| | >|
| | >| //Set defaults for this control
| | >| base.Format =
| | >| DateTimePickerFormat.Short;
| | >|
| | >| //Make sure that our date backup
| | >| is populated
| | >| mDateTime = base.Value;
| | >| mChecked = base.Checked;
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Properties
| | >|
| | >| [DesignerSerializationVisibility
| | >| (DesignerSerializationVisibility.Visible)]
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| set
| | >| {
| | >| if(value)
| | >| {
| | >|
| | >| base.CalendarMonthBackground = mLockedColor;
| | >| }
| | >| else
| | >| {
| | >|
| | >| base.CalendarMonthBackground = mBackColor;
| | >| }
| | >|
| | >| mReadOnly = value;
| | >| if(OnReadOnlyChanged !=
| | >| null)
| | >| {
| | >| OnReadOnlyChanged
| | >| (this, new OnReadOnlyChangedEventArgs(value));
| | >| }
| | >| }
| | >| }
| | >|
| | >| [DesignerSerializationVisibility
| | >| (DesignerSerializationVisibility.Visible)]
| | >| public Color LockedColor
| | >| {
| | >| get
| | >| {
| | >| return mLockedColor;
| | >| }
| | >| set
| | >| {
| | >| mLockedColor = value;
| | >| }
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Public Overridden Properties
| | >| public override Color BackColor
| | >| {
| | >| get
| | >| {
| | >| return base.BackColor;
| | >| }
| | >| set
| | >| {
| | >| mBackColor = value;
| | >| if(!mReadOnly)
| | >| {
| | >| base.BackColor =
| | >| value;
| | >| }
| | >| }
| | >| }
| | >| public new OptionalDateTime Value
| | >| {
| | >| set
| | >| {
| | >| if(value.GetValue() == "")
| | >| {
| | >| base.Checked =
| | >| false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =
| | >| DateTime.Parse(value.GetValue());
| | >| }
| | >|
| | >| }
| | >| get
| | >| {
| | >| if(base.Checked)
| | >| {
| | >| return new
| | >| OptionalDateTime(base.Value);
| | >| }
| | >| else
| | >| {
| | >| return new
| | >| OptionalDateTime();
| | >| }
| | >| }
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Overridden Events
| | >|
| | >| protected override void OnValueChanged
| | >| (EventArgs eventargs)
| | >| {
| | >| base.OnValueChanged (eventargs);
| | >|
| | >| if(mReadOnly)
| | >| {
| | >| //We need to set the
| | >| value of the control back to
| | >| //the stored value, since
| | >| it is read only
| | >| if(base.Value !=
| | >| mDateTime)
| | >| {
| | >| base.Value =
| | >| mDateTime;
| | >| }
| | >| if(base.Checked !=
| | >| mChecked)
| | >| {
| | >| base.Checked =
| | >| mChecked;
| | >| }
| | >| }
| | >| else
| | >| {
| | >| //Store the value for
| | >| when it's read only
| | >| mDateTime = base.Value;
| | >| mChecked = base.Checked;
| | >| }
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Public Methods
| | >| public void Initialise(OptionalDateTime
| | >| Value)
| | >| {
| | >| //Temporarily set the control to
| | >| not ReadOnly.
| | >| bool mTempReadOnly = mReadOnly;
| | >| if(mReadOnly)
| | >| {
| | >| mReadOnly = false;
| | >| }
| | >|
| | >| if(Value.GetValue() == "")
| | >| {
| | >| base.Checked = false;
| | >| mChecked = false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =
| | >| DateTime.Parse(Value.GetValue());
| | >| base.Checked = true;
| | >| mDateTime = base.Value;
| | >| mChecked = true;
| | >| }
| | >|
| | >| //Make sure the ReadOnly value is
| | >| returned to normal
| | >| mReadOnly = mTempReadOnly;
| | >| }
| | >| public void Initialise(DateTime Value)
| | >| {
| | >| Initialise(new OptionalDateTime
| | >| (Value));
| | >| }
| | >| public void Initialise()
| | >| {
| | >| Initialise(new OptionalDateTime
| | >| ());
| | >| }
| | >| #endregion
| | >| }
| | >| }
| | >|
| | >| ##############OptionalDateTime Source##########
| | >|
| | >| [Serializable()]
| | >| public class OptionalDateTime
| | >| {
| | >| #region Enum
| | >| /// <summary>
| | >| /// Formats available - extend as
| | >| required, but remember to update <see
| | cref="GetValue"/>.
| | >| /// </summary>
| | >| public enum enumDateTimeFormat
| | >| {
| | >| /// <summary>
| | >| /// LongDateFormat
| | >| /// </summary>
| | >| LongDateFormat,
| | >| /// <summary>
| | >| /// LongTimeFormat
| | >| /// </summary>
| | >| LongTimeFormat,
| | >| /// <summary>
| | >| /// ShortDateFormat
| | >| /// </summary>
| | >| ShortDateFormat,
| | >| /// <summary>
| | >| /// ShortTimeFormat
| | >| /// </summary>
| | >| ShortTimeFormat
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >| private DateTime mDate;
| | >| private bool mIsNull;
| | >| #endregion
| | >|
| | >| #region Constructor
| | >| /// <summary>
| | >| /// Constructor - initialises a null
| | >| OptionalDateTime
| | >| /// </summary>
| | >| public OptionalDateTime()
| | >| {
| | >| mIsNull = true;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTime to contain the value of a string.
| | >| /// If the string is not a valid
| | >| DateTime, the object is set to contain a null date.
| | >| /// </summary>
| | >| /// <param name="value">A string
| | >| representing a valid date.</param>
| | >| public OptionalDateTime(string value)
| | >| {
| | >| SetValue(value);
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTime to contain the value of a DateTime.
| | >| /// </summary>
| | >| /// <param name="value">A DateTime value
| | >| type.</param>
| | >| public OptionalDateTime(DateTime value)
| | >| {
| | >| SetValue(value);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Methods
| | >| /// <summary>
| | >| /// Set the value of the object to equal
| | >| that of a DateTime.
| | >| /// </summary>
| | >| /// <param name="value">A
| | >| DateTime.</param>
| | >| public void SetValue(DateTime value)
| | >| {
| | >| mDate = value;
| | >| mIsNull = false;
| | >| }
| | >| /// <summary>
| | >| /// Set the value of the object to equal
| | >| that of a string. If the string is not a valid
| | >| /// DateTime, the object is set to
| | >| contain a null date.
| | >| /// </summary>
| | >| /// <param name="value">A string
| | >| representing a valid date.</param>
| | >| public void SetValue(string value)
| | >| {
| | >| if(value == null || value == "")
| | >| {
| | >| mIsNull = true;
| | >| }
| | >| else
| | >| {
| | >| try
| | >| {
| | >| mDate =
| | >| DateTime.Parse(value);
| | >| mIsNull = false;
| | >| }
| | >| catch
| | >| {
| | >| throw new
| | >| ArgumentException("The string entered cannot be
| | converted
| | >| to a DateTime", "value");
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a
| | >| string with optional formatting.
| | >| /// </summary>
| | >| /// <param name="Format">The format to
| | >| return.</param>
| | >| /// <returns>A string containing the
| | >| correctly formatted date.</returns>
| | >| public string GetValue(enumDateTimeFormat
| | >| Format)
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| return "";
| | >| }
| | >| else
| | >| {
| | >| switch(Format)
| | >| {
| | >| case
| | >| enumDateTimeFormat.LongDateFormat:
| | >| return
| | >| mDate.ToLongDateString();
| | >| case
| | >| enumDateTimeFormat.LongTimeFormat:
| | >| return
| | >| mDate.ToLongTimeString();
| | >| case
| | >| enumDateTimeFormat.ShortDateFormat:
| | >| return
| | >| mDate.ToShortDateString();
| | >| case
| | >| enumDateTimeFormat.ShortTimeFormat:
| | >| return
| | >| mDate.ToShortTimeString();
| | >| default:
| | >| throw new
| | >| UnhandledDateFormatException(Format);
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a
| | >| ShortDateString.
| | >| /// </summary>
| | >| /// <returns></returns>
| | >| public string GetValue()
| | >| {
| | >| return GetValue
| | >| (enumDateTimeFormat.ShortDateFormat);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Override Methods
| | >| /// <summary>
| | >| /// Passes a string containing the date
| | >| in <see cref="enumDateTimeFormat.ShortDateFormat"/>.
| | >| /// </summary>
| | >| /// <returns>The date returned. Passes an
| | >| empty string for blank (null) dates.</returns>
| | >| public override string ToString()
| | >| {
| | >| return GetValue();
| | >| }
| | >| #endregion
| | >|
| | >| #region Properties
| | >| /// <summary>
| | >| /// Returns the date of the
| | >| OptionalDateTime as a DateTime type. Raises the
| | >| /// <see
| | >| cref="OptionalDateTimeIsNullException"/> if the
| | >| OptionalDateTime is
| | >| /// blank (null). Check the <see
| | >| cref="IsNull"/> property before calling this
| | >| /// method to avoid the exception.
| | >| /// </summary>
| | >| public DateTime GetDateTime
| | >| {
| | >| get
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| throw new
| | >| OptionalDateTimeIsNullException();
| | >| }
| | >| return mDate;
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Gets a boolean value indicating
| | >| whether the OptionalDateTime is blank (null).
| | >| /// </summary>
| | >| public bool IsNull
| | >| {
| | >| get
| | >| {
| | >| return mIsNull;
| | >| }
| | >| }
| | >| #endregion
| | >| }
| | >|
| | >| thanks in advance
| | >|
| | >
| | >.
| | >
| |
|

Nov 15 '05 #8
Guy
Thanks Jeffrey,

there is some interesting stuff in the workarounds you
have given, hopefully the next version will be fixed
anyway!

Cheers

Guy
-----Original Message-----

Hi Guy,

Second way:

I found that the normal mouse click selection of DateTimePicker will fires3 WM_NOTIFY messages which code are NM_RELEASECAPTURE, MCN_SELCHANGE,MCN_SELECT. And if I filter MCN_SELCHANGE, MCN_SELECT message, the calendarwill not change its value. But the problem is if I filter these 2 message,the Calendar will not fade away when I click a item. It will stay thethere. So we must kill it. I use P/invoke the Win32 API DestroyWindow toget this done.

using System.Runtime .InteropServices ;

public bool readonlyval=false;
private DateTime oldval;

oldval=this.Value ; // in control's constructor

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=MCN_FIRST + 1;
private const int MCN_SELECT=MCN_FIRST + 4;
private int WM_NOTIFY=0x004E;

[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hWnd1,IntPtrhWnd2,string lpsz1,string lpsz2);

[DllImport("user32.dll")]
public static extern bool DestroyWindow(IntPtr hwnd);

[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(this.readonlyval==true)
{
if(m.Msg==WM_NOTIFY)
{
if(m.HWnd==this.Handle)
{
NMHDR nm1=(NMHDR) Marshal.PtrToStructure(m.LParam,typeof(NMHDR)); if (nm1.code==MCN_SELCHANGE) {
return;
}
if(nm1.code ==MCN_SELECT)
{
IntPtr calendarhandle=FindWindowEx(IntPtr.Zero ,IntPtr.Zero,"SysMonthCal32",String.Empty);
DestroyWindow (calendarhandle); return;
}
}
}
}
base.WndProc (ref m);
}

Have a nice day!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
--------------------
| Newsgroups: microsoft.public.dotnet.languages.csharp
| From: v-*****@online.microsoft.com ("Jeffrey Tan [MSFT]")| Organization: Microsoft
| Date: Wed, 29 Oct 2003 03:46:45 GMT
| Subject: RE: bug using Application.EnableVisualStyles () withdatetimepicker control
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
|
|
| Hi Guy,
|
| Sorry for letting you waiting so long time.
| In this time, I did a lot of research into DateTimePicker control and| wanted to find a workaround for you.
| Here, I provide you 2 ways of workaround:
| First: override its OnCloseUp method and reset its value to its original| value. But this is not enough, when you open the datetimepicker, you can| use keyboard arrow to navigate the selection, and the value displayedwill
| also change in the textbox( For the moment, we call it textbox). I thinkwe
| should not let this happen, the value should stay the same. But justreset
| value in the OnValueChanged method seems work well on keyboardnavigation,
| but will again change the value when closing the calendar.(It seems that| the OnCloseUp abated). So I hooked into this control, and filter its| MCN_SELCHANGE notification in WM_NOTIFY message.
|
| using System.Runtime .InteropServices ;
| public bool readonlyval=false;
| private DateTime oldval;
|
| oldval=this.Value; // in this control's constructor
|
| protected override void OnCloseUp(EventArgs eventargs)
| {
| if(readonlyval==true)
| {
| this.Value =oldval;
| }
| oldval=this.Value ;
| base.OnCloseUp (eventargs);
| }
|
| private const int MCN_FIRST=-750;
| private const int MCN_SELCHANGE=MCN_FIRST + 1;
| private int WM_NOTIFY=0x004E;
|
| [StructLayout(LayoutKind.Sequential)]
| public struct NMHDR
| {
| public IntPtr hwndFrom;
| public int idfrom;
| public int code;
| }
|
| protected override void WndProc(ref Message m)
| {
| if(this.readonlyval==true)
| {
| if(m.Msg==WM_NOTIFY)
| {
| if(m.HWnd==this.Handle)
| {
| NMHDR nm1=(NMHDR) Marshal.PtrToStructure(m.LParam,typeof(NMHDR));| if(nm1.code==MCN_SELCHANGE)
| {
| return;
| }
| }
| }
| base.WndProc (ref m);
| }
| }
|
| I use Spy++ to find that the DateTimePicker control will receiveWM_NOTIFY
| message with MCN_SELCHANGE code when selection changes.
| All the const value MCN_SELCHANGE, MCN_FIRST can be found in theC:\Program
| Files\Microsoft Visual Studio\VC98\Include directory *.h files.|
| It works well on my machine. If you have any question, please feel freeto
| tell me.
| I will reply the second way of workaround in another reply post.|
| Jeffrey Tan
| Microsoft Online Partner Support
| Get Secure! - www.microsoft.com/security
| This posting is provided "as is" with no warranties and confers no rights.|
| --------------------
| | Content-Class: urn:content-classes:message
| | From: "guy" <gu*@hcs-ltd.co.uk>
| | Sender: "guy" <gu*@hcs-ltd.co.uk>
| | References: <08****************************@phx.gbl>
| <6i**************@cpmsftngxa06.phx.gbl>
| | Subject: RE: bug using Application.EnableVisualStyles () with| datetimepicker control
| | Date: Tue, 28 Oct 2003 01:26:56 -0800
| | Lines: 601
| | Message-ID: <08****************************@phx.gbl>
| | MIME-Version: 1.0
| | Content-Type: text/plain;
| | charset="iso-8859-1"
| | Content-Transfer-Encoding: 7bit
| | X-Newsreader: Microsoft CDO for Windows 2000
| | Thread-Index: AcOdNaFMO+yabmhBTea+z5L0ii9kXg==
| | X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300| | Newsgroups: microsoft.public.dotnet.languages.csharp
| | Path: cpmsftngxa06.phx.gbl
| | Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.languages.csharp:194627
| | NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| |
| | Ok Jeffrey, ill wait for your reply
| |
| |
| |
| | >-----Original Message-----
| | >
| | >Hi Guy,
| | >
| | >It is an already known issue.
| | >I will do some research on this to find some workaround| | for you.
| | >Thanks for you understanding.
| | >
| | >Best regards,
| | >Jeffrey Tan
| | >Microsoft Online Partner Support
| | >Get Secure! - www.microsoft.com/security
| | >This posting is provided "as is" with no warranties and| | confers no rights.
| | >
| | >--------------------
| | >| Content-Class: urn:content-classes:message
| | >| From: "Guy" <gu*@hcs-ltd.co.uk>
| | >| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| | >| Subject: bug using Application.EnableVisualStyles ()| | with datetimepicker
| | >control
| | >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| | >| Lines: 540
| | >| Message-ID: <085401c39a1d$7c2d0480 $a*******@phx.gbl>| | >| MIME-Version: 1.0
| | >| Content-Type: text/plain;
| | >| charset="iso-8859-1"
| | >| Content-Transfer-Encoding: 7bit
| | >| X-Newsreader: Microsoft CDO for Windows 2000
| | >| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| | >| X-MimeOLE: Produced By Microsoft MimeOLE
| | V5.50.4910.0300
| | >| Newsgroups: microsoft.public.dotnet.languages.csharp| | >| Path: cpmsftngxa06.phx.gbl
| | >| Xref: cpmsftngxa06.phx.gbl
| | microsoft.public.dotnet.languages.csharp:193774
| | >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| | >| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp| | >|
| | >| I have extended the datetimepicker control to
| | incorporate
| | >| a ReadOnly property.
| | >| I have used the new keyword to implement my own
| | version
| | >| of the value property, so that if readonly == true| | then
| | >| it will not set the value of the control and will
| | leave
| | >| the checked status of the checkbox to false when a| | user
| | >| selects a new date.
| | >|
| | >| this works fine when using the control on a win2k
| | machine
| | >| but if we use it on a win XP box and call
| | >| Application.EnableVisualStyles() then it seems to
| | ignore
| | >| my code and check the checkbox and set the value. this| | is
| | >| extremely buggy behaviour! and also the value property| | >| gets called twice (only once on a win2k box).
| | >|
| | >| i have also noticed behaviour changes in the
| | >| label.textalignment property when using XP Visual
| | styles
| | >| aswell. Below is my implementation of the extended| | >| datetimepicker and also the new data type
| | >| (OptionalDateTime) that is used for the value
| | property...
| | >|
| | >| #####LockableDateTimePicker Source###########
| | >|
| | >| using System;
| | >| using System.Collections;
| | >| using System.ComponentModel;
| | >| using System.Drawing;
| | >| using System.Data;
| | >| using System.Windows.Forms;
| | >| using HCS.DataTypes;
| | >|
| | >| namespace HCS.Generic.UI.Controls
| | >| {
| | >| /// <summary>
| | >| /// LockableDateTimePicker is for selecting| | >| dates. It manipulates the OptionalDateTime
| | >| /// class to allow null dates to be handled.| | >| /// </summary>
| | >| public class LockableDateTimePicker :
| | >| DateTimePicker
| | >| {
| | >| #region Clean Up Code
| | >|
| | >| /// <summary>
| | >| /// Clean up any resources being used.| | >| /// </summary>
| | >| protected override void Dispose( bool| | >| disposing )
| | >| {
| | >| if( disposing )
| | >| {
| | >| if(components != null)| | >| {
| | >| components.Dispose| | >| ();
| | >| }
| | >| }
| | >| base.Dispose( disposing );
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Component Designer generated code| | >| /// <summary>
| | >| /// Required method for Designer support -| | >| do not modify
| | >| /// the contents of this method with the| | >| code editor.
| | >| /// </summary>
| | >| private void InitializeComponent()
| | >| {
| | >| components = new
| | >| System.ComponentModel.Container();
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >|
| | >| private System.ComponentModel.Container| | >| components = null;
| | >| private bool mReadOnly;
| | >| private DateTime mDateTime;
| | >| private Color mBackColor;
| | >| private Color mLockedColor;
| | >| private bool mChecked;
| | >|
| | >| #endregion
| | >|
| | >| #region Events
| | >|
| | >| public event OnReadOnlyChangedDelegate| | >| OnReadOnlyChanged;
| | >|
| | >| #endregion
| | >|
| | >| #region EventArgs and Delegates
| | >|
| | >| public class OnReadOnlyChangedEventArgs :| | >| EventArgs
| | >| {
| | >| private bool mReadOnly;
| | >|
| | >| public OnReadOnlyChangedEventArgs| | >| (bool ReadOnly)
| | >| {
| | >| mReadOnly = ReadOnly;| | >| }
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;| | >| }
| | >| }
| | >| }
| | >| public delegate void
| | >| OnReadOnlyChangedDelegate(object sender,
| | >| OnReadOnlyChangedEventArgs e);
| | >|
| | >| #endregion
| | >|
| | >| #region Constructor
| | >|
| | >| public LockableDateTimePicker()
| | >| {
| | >| // This call is required by the| | >| Windows.Forms Form Designer.
| | >| InitializeComponent();
| | >|
| | >| mBackColor =
| | >| base.CalendarMonthBackground;
| | >| mLockedColor =
| | >| base.CalendarMonthBackground;
| | >|
| | >| //Set defaults for this control| | >| base.Format =
| | >| DateTimePickerFormat.Short;
| | >|
| | >| //Make sure that our date backup| | >| is populated
| | >| mDateTime = base.Value;
| | >| mChecked = base.Checked;
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Properties
| | >|
| | >| [DesignerSerializationVisibility
| | >| (DesignerSerializationVisibility.Visible)]
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| set
| | >| {
| | >| if(value)
| | >| {
| | >|
| | >| base.CalendarMonthBackground = mLockedColor;| | >| }
| | >| else
| | >| {
| | >|
| | >| base.CalendarMonthBackground = mBackColor;
| | >| }
| | >|
| | >| mReadOnly = value;
| | >| if (OnReadOnlyChanged !=| | >| null)
| | >| {
| | >| OnReadOnlyChanged| | >| (this, new OnReadOnlyChangedEventArgs(value));
| | >| }
| | >| }
| | >| }
| | >|
| | >| [DesignerSerializationVisibility
| | >| (DesignerSerializationVisibility.Visible)]
| | >| public Color LockedColor
| | >| {
| | >| get
| | >| {
| | >| return mLockedColor;| | >| }
| | >| set
| | >| {
| | >| mLockedColor = value;| | >| }
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Public Overridden Properties| | >| public override Color BackColor
| | >| {
| | >| get
| | >| {
| | >| return base.BackColor;| | >| }
| | >| set
| | >| {
| | >| mBackColor = value;| | >| if(!mReadOnly)
| | >| {
| | >| base.BackColor =| | >| value;
| | >| }
| | >| }
| | >| }
| | >| public new OptionalDateTime Value
| | >| {
| | >| set
| | >| {
| | >| if(value.GetValue () == "")| | >| {
| | >| base.Checked =| | >| false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =| | >| DateTime.Parse(value.GetValue());
| | >| }
| | >|
| | >| }
| | >| get
| | >| {
| | >| if(base.Checked)
| | >| {
| | >| return new| | >| OptionalDateTime(base.Value);
| | >| }
| | >| else
| | >| {
| | >| return new| | >| OptionalDateTime();
| | >| }
| | >| }
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Overridden Events
| | >|
| | >| protected override void OnValueChanged| | >| (EventArgs eventargs)
| | >| {
| | >| base.OnValueChanged (eventargs);| | >|
| | >| if(mReadOnly)
| | >| {
| | >| //We need to set the| | >| value of the control back to
| | >| //the stored value, since| | >| it is read only
| | >| if(base.Value !=
| | >| mDateTime)
| | >| {
| | >| base.Value =| | >| mDateTime;
| | >| }
| | >| if(base.Checked ! =| | >| mChecked)
| | >| {
| | >| base.Checked =| | >| mChecked;
| | >| }
| | >| }
| | >| else
| | >| {
| | >| //Store the value for| | >| when it's read only
| | >| mDateTime = base.Value;| | >| mChecked = base.Checked;| | >| }
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Public Methods
| | >| public void Initialise (OptionalDateTime| | >| Value)
| | >| {
| | >| //Temporarily set the control to| | >| not ReadOnly.
| | >| bool mTempReadOnly = mReadOnly;| | >| if(mReadOnly)
| | >| {
| | >| mReadOnly = false;
| | >| }
| | >|
| | >| if(Value.GetValue() == "")
| | >| {
| | >| base.Checked = false;| | >| mChecked = false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =
| | >| DateTime.Parse(Value.GetValue());
| | >| base.Checked = true;| | >| mDateTime = base.Value;| | >| mChecked = true;
| | >| }
| | >|
| | >| //Make sure the ReadOnly value is| | >| returned to normal
| | >| mReadOnly = mTempReadOnly;
| | >| }
| | >| public void Initialise(DateTime Value)| | >| {
| | >| Initialise(new OptionalDateTime| | >| (Value));
| | >| }
| | >| public void Initialise()
| | >| {
| | >| Initialise(new OptionalDateTime| | >| ());
| | >| }
| | >| #endregion
| | >| }
| | >| }
| | >|
| | >| ##############OptionalDateTime Source##########
| | >|
| | >| [Serializable()]
| | >| public class OptionalDateTime
| | >| {
| | >| #region Enum
| | >| /// <summary>
| | >| /// Formats available - extend as
| | >| required, but remember to update <see
| | cref="GetValue"/>.
| | >| /// </summary>
| | >| public enum enumDateTimeFormat
| | >| {
| | >| /// <summary>
| | >| /// LongDateFormat
| | >| /// </summary>
| | >| LongDateFormat,
| | >| /// <summary>
| | >| /// LongTimeFormat
| | >| /// </summary>
| | >| LongTimeFormat,
| | >| /// <summary>
| | >| /// ShortDateFormat
| | >| /// </summary>
| | >| ShortDateFormat,
| | >| /// <summary>
| | >| /// ShortTimeFormat
| | >| /// </summary>
| | >| ShortTimeFormat
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >| private DateTime mDate;
| | >| private bool mIsNull;
| | >| #endregion
| | >|
| | >| #region Constructor
| | >| /// <summary>
| | >| /// Constructor - initialises a null| | >| OptionalDateTime
| | >| /// </summary>
| | >| public OptionalDateTime()
| | >| {
| | >| mIsNull = true;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTime to contain the value of a string.
| | >| /// If the string is not a valid
| | >| DateTime, the object is set to contain a null date.| | >| /// </summary>
| | >| /// <param name="value">A string
| | >| representing a valid date.</param>
| | >| public OptionalDateTime(string value)| | >| {
| | >| SetValue(value);
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTime to contain the value of a DateTime.| | >| /// </summary>
| | >| /// <param name="value">A DateTime value| | >| type.</param>
| | >| public OptionalDateTime(DateTime value)| | >| {
| | >| SetValue(value);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Methods
| | >| /// <summary>
| | >| /// Set the value of the object to equal| | >| that of a DateTime.
| | >| /// </summary>
| | >| /// <param name="value">A
| | >| DateTime.</param>
| | >| public void SetValue(DateTime value)| | >| {
| | >| mDate = value;
| | >| mIsNull = false;
| | >| }
| | >| /// <summary>
| | >| /// Set the value of the object to equal| | >| that of a string. If the string is not a valid
| | >| /// DateTime, the object is set to| | >| contain a null date.
| | >| /// </summary>
| | >| /// <param name="value">A string
| | >| representing a valid date.</param>
| | >| public void SetValue(string value)
| | >| {
| | >| if(value == null || value == "")| | >| {
| | >| mIsNull = true;
| | >| }
| | >| else
| | >| {
| | >| try
| | >| {
| | >| mDate =
| | >| DateTime.Parse(value);
| | >| mIsNull = false;| | >| }
| | >| catch
| | >| {
| | >| throw new
| | >| ArgumentException("The string entered cannot be
| | converted
| | >| to a DateTime", "value");
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a| | >| string with optional formatting.
| | >| /// </summary>
| | >| /// <param name="Format">The format to| | >| return.</param>
| | >| /// <returns>A string containing the| | >| correctly formatted date.</returns>
| | >| public string GetValue (enumDateTimeFormat| | >| Format)
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| return "";
| | >| }
| | >| else
| | >| {
| | >| switch(Format)
| | >| {
| | >| case
| | >| enumDateTimeFormat.LongDateFormat:
| | >| return| | >| mDate.ToLongDateString();
| | >| case
| | >| enumDateTimeFormat.LongTimeFormat:
| | >| return| | >| mDate.ToLongTimeString();
| | >| case
| | >| enumDateTimeFormat.ShortDateFormat:
| | >| return| | >| mDate.ToShortDateString();
| | >| case
| | >| enumDateTimeFormat.ShortTimeFormat:
| | >| return| | >| mDate.ToShortTimeString();
| | >| default:
| | >| throw new| | >| UnhandledDateFormatException(Format);
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a| | >| ShortDateString.
| | >| /// </summary>
| | >| /// <returns></returns>
| | >| public string GetValue()
| | >| {
| | >| return GetValue
| | >| (enumDateTimeFormat.ShortDateFormat);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Override Methods
| | >| /// <summary>
| | >| /// Passes a string containing the date| | >| in <see cref="enumDateTimeFormat.ShortDateFormat"/>.| | >| /// </summary>
| | >| /// <returns>The date returned. Passes an| | >| empty string for blank (null) dates.</returns>
| | >| public override string ToString()
| | >| {
| | >| return GetValue();
| | >| }
| | >| #endregion
| | >|
| | >| #region Properties
| | >| /// <summary>
| | >| /// Returns the date of the
| | >| OptionalDateTime as a DateTime type. Raises the
| | >| /// <see
| | >| cref="OptionalDateTimeIsNullException"/> if the
| | >| OptionalDateTime is
| | >| /// blank (null). Check the <see
| | >| cref="IsNull"/> property before calling this
| | >| /// method to avoid the exception.
| | >| /// </summary>
| | >| public DateTime GetDateTime
| | >| {
| | >| get
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| throw new
| | >| OptionalDateTimeIsNullException();
| | >| }
| | >| return mDate;
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Gets a boolean value indicating| | >| whether the OptionalDateTime is blank (null).
| | >| /// </summary>
| | >| public bool IsNull
| | >| {
| | >| get
| | >| {
| | >| return mIsNull;
| | >| }
| | >| }
| | >| #endregion
| | >| }
| | >|
| | >| thanks in advance
| | >|
| | >
| | >.
| | >
| |
|

.

Nov 15 '05 #9

Hi Guy,

I am glad my workaround makes sense to you.
We have recognized this issue, and registered this issue in our document.
Thanks for your suggestion.
Have a nice day!

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Content-Class: urn:content-classes:message
| From: "Guy" <gu*@hcs-ltd.co.uk>
| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| References: <08****************************@phx.gbl>
<6i**************@cpmsftngxa06.phx.gbl>
<08****************************@phx.gbl>
<kM**************@cpmsftngxa06.phx.gbl>
<lG**************@cpmsftngxa06.phx.gbl>
| Subject: RE: bug using Application.EnableVisualStyles() with
datetimepicker control
| Date: Wed, 29 Oct 2003 07:25:20 -0800
| Lines: 936
| Message-ID: <00****************************@phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Thread-Index: AcOeMN0MVnak9MhtTgyiX4kq1GG8Qw==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:195079
| NNTP-Posting-Host: TK2MSFTNGXA09 10.40.1.161
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Thanks Jeffrey,
|
| there is some interesting stuff in the workarounds you
| have given, hopefully the next version will be fixed
| anyway!
|
| Cheers
|
| Guy
|
|
|
| >-----Original Message-----
| >
| >Hi Guy,
| >
| >Second way:
| >
| >I found that the normal mouse click selection of
| DateTimePicker will fires
| >3 WM_NOTIFY messages which code are NM_RELEASECAPTURE,
| MCN_SELCHANGE,
| >MCN_SELECT. And if I filter MCN_SELCHANGE, MCN_SELECT
| message, the calendar
| >will not change its value. But the problem is if I
| filter these 2 message,
| >the Calendar will not fade away when I click a item. It
| will stay the
| >there. So we must kill it. I use P/invoke the Win32 API
| DestroyWindow to
| >get this done.
| >
| >using System.Runtime .InteropServices ;
| >
| >public bool readonlyval=false;
| >private DateTime oldval;
| >
| >oldval=this.Value ; // in control's constructor
| >
| >private const int MCN_FIRST=-750;
| >private const int MCN_SELCHANGE=MCN_FIRST + 1;
| >private const int MCN_SELECT=MCN_FIRST + 4;
| >private int WM_NOTIFY=0x004E;
| >
| >[DllImport("user32.dll")]
| >public static extern IntPtr FindWindowEx(IntPtr
| hWnd1,IntPtr
| >hWnd2,string lpsz1,string lpsz2);
| >
| >[DllImport("user32.dll")]
| >public static extern bool DestroyWindow(IntPtr hwnd);
| >
| >[StructLayout(LayoutKind.Sequential)]
| > public struct NMHDR
| >{
| > public IntPtr hwndFrom;
| > public int idfrom;
| > public int code;
| >}
| >
| >protected override void WndProc(ref Message m)
| >{
| > if(this.readonlyval==true)
| > {
| > if(m.Msg==WM_NOTIFY)
| > {
| > if(m.HWnd==this.Handle)
| > {
| > NMHDR nm1=(NMHDR)
| Marshal.PtrToStructure(m.LParam,typeof(NMHDR));
| > if
| (nm1.code==MCN_SELCHANGE)
| > {
| > return;
| > }
| > if(nm1.code ==MCN_SELECT)
| > {
| > IntPtr
| calendarhandle=FindWindowEx(IntPtr.Zero ,IntPtr.Zero
| >,"SysMonthCal32",String.Empty);
| > DestroyWindow
| (calendarhandle);
| > return;
| > }
| > }
| > }
| > }
| > base.WndProc (ref m);
| >}
| >
| >Have a nice day!
| >
| >Best regards,
| >Jeffrey Tan
| >Microsoft Online Partner Support
| >Get Secure! - www.microsoft.com/security
| >This posting is provided "as is" with no warranties and
| confers no rights.
| >
| >--------------------
| >| Newsgroups: microsoft.public.dotnet.languages.csharp
| >| From: v-*****@online.microsoft.com ("Jeffrey Tan
| [MSFT]")
| >| Organization: Microsoft
| >| Date: Wed, 29 Oct 2003 03:46:45 GMT
| >| Subject: RE: bug using Application.EnableVisualStyles
| () with
| >datetimepicker control
| >| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| >| MIME-Version: 1.0
| >| Content-Type: text/plain
| >| Content-Transfer-Encoding: 7bit
| >|
| >|
| >| Hi Guy,
| >|
| >| Sorry for letting you waiting so long time.
| >| In this time, I did a lot of research into
| DateTimePicker control and
| >| wanted to find a workaround for you.
| >| Here, I provide you 2 ways of workaround:
| >| First: override its OnCloseUp method and reset its
| value to its original
| >| value. But this is not enough, when you open the
| datetimepicker, you can
| >| use keyboard arrow to navigate the selection, and the
| value displayed
| >will
| >| also change in the textbox( For the moment, we call it
| textbox). I think
| >we
| >| should not let this happen, the value should stay the
| same. But just
| >reset
| >| value in the OnValueChanged method seems work well on
| keyboard
| >navigation,
| >| but will again change the value when closing the
| calendar.(It seems that
| >| the OnCloseUp abated). So I hooked into this control,
| and filter its
| >| MCN_SELCHANGE notification in WM_NOTIFY message.
| >|
| >| using System.Runtime .InteropServices ;
| >| public bool readonlyval=false;
| >| private DateTime oldval;
| >|
| >| oldval=this.Value; // in this control's constructor
| >|
| >| protected override void OnCloseUp(EventArgs eventargs)
| >| {
| >| if(readonlyval==true)
| >| {
| >| this.Value =oldval;
| >| }
| >| oldval=this.Value ;
| >| base.OnCloseUp (eventargs);
| >| }
| >|
| >| private const int MCN_FIRST=-750;
| >| private const int MCN_SELCHANGE=MCN_FIRST + 1;
| >| private int WM_NOTIFY=0x004E;
| >|
| >| [StructLayout(LayoutKind.Sequential)]
| >| public struct NMHDR
| >| {
| >| public IntPtr hwndFrom;
| >| public int idfrom;
| >| public int code;
| >| }
| >|
| >| protected override void WndProc(ref Message m)
| >| {
| >| if(this.readonlyval==true)
| >| {
| >| if(m.Msg==WM_NOTIFY)
| >| {
| >| if(m.HWnd==this.Handle)
| >| {
| >| NMHDR nm1=(NMHDR)
| Marshal.PtrToStructure(m.LParam,typeof(NMHDR));
| >| if(nm1.code==MCN_SELCHANGE)
| >| {
| >| return;
| >| }
| >| }
| >| }
| >| base.WndProc (ref m);
| >| }
| >| }
| >|
| >| I use Spy++ to find that the DateTimePicker control
| will receive
| >WM_NOTIFY
| >| message with MCN_SELCHANGE code when selection changes.
| >| All the const value MCN_SELCHANGE, MCN_FIRST can be
| found in the
| >C:\Program
| >| Files\Microsoft Visual Studio\VC98\Include directory
| *.h files.
| >|
| >| It works well on my machine. If you have any question,
| please feel free
| >to
| >| tell me.
| >| I will reply the second way of workaround in another
| reply post.
| >|
| >| Jeffrey Tan
| >| Microsoft Online Partner Support
| >| Get Secure! - www.microsoft.com/security
| >| This posting is provided "as is" with no warranties
| and confers no rights.
| >|
| >| --------------------
| >| | Content-Class: urn:content-classes:message
| >| | From: "guy" <gu*@hcs-ltd.co.uk>
| >| | Sender: "guy" <gu*@hcs-ltd.co.uk>
| >| | References: <08****************************@phx.gbl>
| >| <6i**************@cpmsftngxa06.phx.gbl>
| >| | Subject: RE: bug using Application.EnableVisualStyles
| () with
| >| datetimepicker control
| >| | Date: Tue, 28 Oct 2003 01:26:56 -0800
| >| | Lines: 601
| >| | Message-ID: <08****************************@phx.gbl>
| >| | MIME-Version: 1.0
| >| | Content-Type: text/plain;
| >| | charset="iso-8859-1"
| >| | Content-Transfer-Encoding: 7bit
| >| | X-Newsreader: Microsoft CDO for Windows 2000
| >| | Thread-Index: AcOdNaFMO+yabmhBTea+z5L0ii9kXg==
| >| | X-MimeOLE: Produced By Microsoft MimeOLE
| V5.50.4910.0300
| >| | Newsgroups: microsoft.public.dotnet.languages.csharp
| >| | Path: cpmsftngxa06.phx.gbl
| >| | Xref: cpmsftngxa06.phx.gbl
| >microsoft.public.dotnet.languages.csharp:194627
| >| | NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| >| | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| >| |
| >| | Ok Jeffrey, ill wait for your reply
| >| |
| >| |
| >| |
| >| | >-----Original Message-----
| >| | >
| >| | >Hi Guy,
| >| | >
| >| | >It is an already known issue.
| >| | >I will do some research on this to find some
| workaround
| >| | for you.
| >| | >Thanks for you understanding.
| >| | >
| >| | >Best regards,
| >| | >Jeffrey Tan
| >| | >Microsoft Online Partner Support
| >| | >Get Secure! - www.microsoft.com/security
| >| | >This posting is provided "as is" with no warranties
| and
| >| | confers no rights.
| >| | >
| >| | >--------------------
| >| | >| Content-Class: urn:content-classes:message
| >| | >| From: "Guy" <gu*@hcs-ltd.co.uk>
| >| | >| Sender: "Guy" <gu*@hcs-ltd.co.uk>
| >| | >| Subject: bug using Application.EnableVisualStyles
| ()
| >| | with datetimepicker
| >| | >control
| >| | >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| >| | >| Lines: 540
| >| | >| Message-ID: <085401c39a1d$7c2d0480
| $a*******@phx.gbl>
| >| | >| MIME-Version: 1.0
| >| | >| Content-Type: text/plain;
| >| | >| charset="iso-8859-1"
| >| | >| Content-Transfer-Encoding: 7bit
| >| | >| X-Newsreader: Microsoft CDO for Windows 2000
| >| | >| Thread-Index: AcOaHXwtoiMaL/QOSWuDQUgjMGLnAw==
| >| | >| X-MimeOLE: Produced By Microsoft MimeOLE
| >| | V5.50.4910.0300
| >| | >| Newsgroups:
| microsoft.public.dotnet.languages.csharp
| >| | >| Path: cpmsftngxa06.phx.gbl
| >| | >| Xref: cpmsftngxa06.phx.gbl
| >| | microsoft.public.dotnet.languages.csharp:193774
| >| | >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| >| | >| X-Tomcat-NG:
| microsoft.public.dotnet.languages.csharp
| >| | >|
| >| | >| I have extended the datetimepicker control to
| >| | incorporate
| >| | >| a ReadOnly property.
| >| | >| I have used the new keyword to implement my own
| >| | version
| >| | >| of the value property, so that if readonly ==
| true
| >| | then
| >| | >| it will not set the value of the control and will
| >| | leave
| >| | >| the checked status of the checkbox to false when
| a
| >| | user
| >| | >| selects a new date.
| >| | >|
| >| | >| this works fine when using the control on a win2k
| >| | machine
| >| | >| but if we use it on a win XP box and call
| >| | >| Application.EnableVisualStyles() then it seems to
| >| | ignore
| >| | >| my code and check the checkbox and set the value.
| this
| >| | is
| >| | >| extremely buggy behaviour! and also the value
| property
| >| | >| gets called twice (only once on a win2k box).
| >| | >|
| >| | >| i have also noticed behaviour changes in the
| >| | >| label.textalignment property when using XP Visual
| >| | styles
| >| | >| aswell. Below is my implementation of the
| extended
| >| | >| datetimepicker and also the new data type
| >| | >| (OptionalDateTime) that is used for the value
| >| | property...
| >| | >|
| >| | >| #####LockableDateTimePicker Source###########
| >| | >|
| >| | >| using System;
| >| | >| using System.Collections;
| >| | >| using System.ComponentModel;
| >| | >| using System.Drawing;
| >| | >| using System.Data;
| >| | >| using System.Windows.Forms;
| >| | >| using HCS.DataTypes;
| >| | >|
| >| | >| namespace HCS.Generic.UI.Controls
| >| | >| {
| >| | >| /// <summary>
| >| | >| /// LockableDateTimePicker is for
| selecting
| >| | >| dates. It manipulates the OptionalDateTime
| >| | >| /// class to allow null dates to be
| handled.
| >| | >| /// </summary>
| >| | >| public class LockableDateTimePicker :
| >| | >| DateTimePicker
| >| | >| {
| >| | >| #region Clean Up Code
| >| | >|
| >| | >| /// <summary>
| >| | >| /// Clean up any resources being
| used.
| >| | >| /// </summary>
| >| | >| protected override void Dispose(
| bool
| >| | >| disposing )
| >| | >| {
| >| | >| if( disposing )
| >| | >| {
| >| | >| if(components !=
| null)
| >| | >| {
| >| | >|
| components.Dispose
| >| | >| ();
| >| | >| }
| >| | >| }
| >| | >| base.Dispose( disposing );
| >| | >| }
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Component Designer
| generated code
| >| | >| /// <summary>
| >| | >| /// Required method for Designer
| support -
| >| | >| do not modify
| >| | >| /// the contents of this method
| with the
| >| | >| code editor.
| >| | >| /// </summary>
| >| | >| private void InitializeComponent()
| >| | >| {
| >| | >| components = new
| >| | >| System.ComponentModel.Container();
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Fields
| >| | >|
| >| | >| private
| System.ComponentModel.Container
| >| | >| components = null;
| >| | >| private bool mReadOnly;
| >| | >| private DateTime mDateTime;
| >| | >| private Color mBackColor;
| >| | >| private Color mLockedColor;
| >| | >| private bool mChecked;
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Events
| >| | >|
| >| | >| public event
| OnReadOnlyChangedDelegate
| >| | >| OnReadOnlyChanged;
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region EventArgs and Delegates
| >| | >|
| >| | >| public class
| OnReadOnlyChangedEventArgs :
| >| | >| EventArgs
| >| | >| {
| >| | >| private bool mReadOnly;
| >| | >|
| >| | >| public
| OnReadOnlyChangedEventArgs
| >| | >| (bool ReadOnly)
| >| | >| {
| >| | >| mReadOnly =
| ReadOnly;
| >| | >| }
| >| | >| public bool ReadOnly
| >| | >| {
| >| | >| get
| >| | >| {
| >| | >| return
| mReadOnly;
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >| public delegate void
| >| | >| OnReadOnlyChangedDelegate(object sender,
| >| | >| OnReadOnlyChangedEventArgs e);
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Constructor
| >| | >|
| >| | >| public LockableDateTimePicker()
| >| | >| {
| >| | >| // This call is required
| by the
| >| | >| Windows.Forms Form Designer.
| >| | >| InitializeComponent();
| >| | >|
| >| | >| mBackColor =
| >| | >| base.CalendarMonthBackground;
| >| | >| mLockedColor =
| >| | >| base.CalendarMonthBackground;
| >| | >|
| >| | >| //Set defaults for this
| control
| >| | >| base.Format =
| >| | >| DateTimePickerFormat.Short;
| >| | >|
| >| | >| //Make sure that our date
| backup
| >| | >| is populated
| >| | >| mDateTime = base.Value;
| >| | >| mChecked = base.Checked;
| >| | >| }
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Properties
| >| | >|
| >| | >| [DesignerSerializationVisibility
| >| | >| (DesignerSerializationVisibility.Visible)]
| >| | >| public bool ReadOnly
| >| | >| {
| >| | >| get
| >| | >| {
| >| | >| return mReadOnly;
| >| | >| }
| >| | >| set
| >| | >| {
| >| | >| if(value)
| >| | >| {
| >| | >|
| >| | >| base.CalendarMonthBackground =
| mLockedColor;
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >|
| >| | >| base.CalendarMonthBackground = mBackColor;
| >| | >| }
| >| | >|
| >| | >| mReadOnly = value;
| >| | >| if
| (OnReadOnlyChanged !=
| >| | >| null)
| >| | >| {
| >| | >|
| OnReadOnlyChanged
| >| | >| (this, new OnReadOnlyChangedEventArgs(value));
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >|
| >| | >| [DesignerSerializationVisibility
| >| | >| (DesignerSerializationVisibility.Visible)]
| >| | >| public Color LockedColor
| >| | >| {
| >| | >| get
| >| | >| {
| >| | >| return
| mLockedColor;
| >| | >| }
| >| | >| set
| >| | >| {
| >| | >| mLockedColor =
| value;
| >| | >| }
| >| | >| }
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Public Overridden
| Properties
| >| | >| public override Color BackColor
| >| | >| {
| >| | >| get
| >| | >| {
| >| | >| return
| base.BackColor;
| >| | >| }
| >| | >| set
| >| | >| {
| >| | >| mBackColor =
| value;
| >| | >| if(!mReadOnly)
| >| | >| {
| >| | >|
| base.BackColor =
| >| | >| value;
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >| public new OptionalDateTime Value
| >| | >| {
| >| | >| set
| >| | >| {
| >| | >| if(value.GetValue
| () == "")
| >| | >| {
| >| | >|
| base.Checked =
| >| | >| false;
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >|
| base.Value =
| >| | >| DateTime.Parse(value.GetValue());
| >| | >| }
| >| | >|
| >| | >| }
| >| | >| get
| >| | >| {
| >| | >| if(base.Checked)
| >| | >| {
| >| | >| return
| new
| >| | >| OptionalDateTime(base.Value);
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >| return
| new
| >| | >| OptionalDateTime();
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Public Overridden Events
| >| | >|
| >| | >| protected override void
| OnValueChanged
| >| | >| (EventArgs eventargs)
| >| | >| {
| >| | >| base.OnValueChanged
| (eventargs);
| >| | >|
| >| | >| if(mReadOnly)
| >| | >| {
| >| | >| //We need to set
| the
| >| | >| value of the control back to
| >| | >| //the stored
| value, since
| >| | >| it is read only
| >| | >| if(base.Value !=
| >| | >| mDateTime)
| >| | >| {
| >| | >|
| base.Value =
| >| | >| mDateTime;
| >| | >| }
| >| | >| if(base.Checked !
| =
| >| | >| mChecked)
| >| | >| {
| >| | >|
| base.Checked =
| >| | >| mChecked;
| >| | >| }
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >| //Store the value
| for
| >| | >| when it's read only
| >| | >| mDateTime =
| base.Value;
| >| | >| mChecked =
| base.Checked;
| >| | >| }
| >| | >| }
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Public Methods
| >| | >| public void Initialise
| (OptionalDateTime
| >| | >| Value)
| >| | >| {
| >| | >| //Temporarily set the
| control to
| >| | >| not ReadOnly.
| >| | >| bool mTempReadOnly =
| mReadOnly;
| >| | >| if(mReadOnly)
| >| | >| {
| >| | >| mReadOnly = false;
| >| | >| }
| >| | >|
| >| | >| if(Value.GetValue() == "")
| >| | >| {
| >| | >| base.Checked =
| false;
| >| | >| mChecked = false;
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >| base.Value =
| >| | >| DateTime.Parse(Value.GetValue());
| >| | >| base.Checked =
| true;
| >| | >| mDateTime =
| base.Value;
| >| | >| mChecked = true;
| >| | >| }
| >| | >|
| >| | >| //Make sure the ReadOnly
| value is
| >| | >| returned to normal
| >| | >| mReadOnly = mTempReadOnly;
| >| | >| }
| >| | >| public void Initialise(DateTime
| Value)
| >| | >| {
| >| | >| Initialise(new
| OptionalDateTime
| >| | >| (Value));
| >| | >| }
| >| | >| public void Initialise()
| >| | >| {
| >| | >| Initialise(new
| OptionalDateTime
| >| | >| ());
| >| | >| }
| >| | >| #endregion
| >| | >| }
| >| | >| }
| >| | >|
| >| | >| ##############OptionalDateTime Source##########
| >| | >|
| >| | >| [Serializable()]
| >| | >| public class OptionalDateTime
| >| | >| {
| >| | >| #region Enum
| >| | >| /// <summary>
| >| | >| /// Formats available - extend as
| >| | >| required, but remember to update <see
| >| | cref="GetValue"/>.
| >| | >| /// </summary>
| >| | >| public enum enumDateTimeFormat
| >| | >| {
| >| | >| /// <summary>
| >| | >| /// LongDateFormat
| >| | >| /// </summary>
| >| | >| LongDateFormat,
| >| | >| /// <summary>
| >| | >| /// LongTimeFormat
| >| | >| /// </summary>
| >| | >| LongTimeFormat,
| >| | >| /// <summary>
| >| | >| /// ShortDateFormat
| >| | >| /// </summary>
| >| | >| ShortDateFormat,
| >| | >| /// <summary>
| >| | >| /// ShortTimeFormat
| >| | >| /// </summary>
| >| | >| ShortTimeFormat
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Fields
| >| | >| private DateTime mDate;
| >| | >| private bool mIsNull;
| >| | >| #endregion
| >| | >|
| >| | >| #region Constructor
| >| | >| /// <summary>
| >| | >| /// Constructor - initialises a
| null
| >| | >| OptionalDateTime
| >| | >| /// </summary>
| >| | >| public OptionalDateTime()
| >| | >| {
| >| | >| mIsNull = true;
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Constructor - initialise an
| >| | >| OptionalDateTime to contain the value of a string.
| >| | >| /// If the string is not a valid
| >| | >| DateTime, the object is set to contain a null
| date.
| >| | >| /// </summary>
| >| | >| /// <param name="value">A string
| >| | >| representing a valid date.</param>
| >| | >| public OptionalDateTime(string
| value)
| >| | >| {
| >| | >| SetValue(value);
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Constructor - initialise an
| >| | >| OptionalDateTime to contain the value of a
| DateTime.
| >| | >| /// </summary>
| >| | >| /// <param name="value">A
| DateTime value
| >| | >| type.</param>
| >| | >| public OptionalDateTime(DateTime
| value)
| >| | >| {
| >| | >| SetValue(value);
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Public Methods
| >| | >| /// <summary>
| >| | >| /// Set the value of the object
| to equal
| >| | >| that of a DateTime.
| >| | >| /// </summary>
| >| | >| /// <param name="value">A
| >| | >| DateTime.</param>
| >| | >| public void SetValue(DateTime
| value)
| >| | >| {
| >| | >| mDate = value;
| >| | >| mIsNull = false;
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Set the value of the object
| to equal
| >| | >| that of a string. If the string is not a valid
| >| | >| /// DateTime, the object is set
| to
| >| | >| contain a null date.
| >| | >| /// </summary>
| >| | >| /// <param name="value">A string
| >| | >| representing a valid date.</param>
| >| | >| public void SetValue(string value)
| >| | >| {
| >| | >| if(value == null || value
| == "")
| >| | >| {
| >| | >| mIsNull = true;
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >| try
| >| | >| {
| >| | >| mDate =
| >| | >| DateTime.Parse(value);
| >| | >| mIsNull =
| false;
| >| | >| }
| >| | >| catch
| >| | >| {
| >| | >| throw new
| >| | >| ArgumentException("The string entered cannot be
| >| | converted
| >| | >| to a DateTime", "value");
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Return the value of the
| object as a
| >| | >| string with optional formatting.
| >| | >| /// </summary>
| >| | >| /// <param name="Format">The
| format to
| >| | >| return.</param>
| >| | >| /// <returns>A string containing
| the
| >| | >| correctly formatted date.</returns>
| >| | >| public string GetValue
| (enumDateTimeFormat
| >| | >| Format)
| >| | >| {
| >| | >| if(mIsNull)
| >| | >| {
| >| | >| return "";
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >| switch(Format)
| >| | >| {
| >| | >| case
| >| | >| enumDateTimeFormat.LongDateFormat:
| >| | >|
| return
| >| | >| mDate.ToLongDateString();
| >| | >| case
| >| | >| enumDateTimeFormat.LongTimeFormat:
| >| | >|
| return
| >| | >| mDate.ToLongTimeString();
| >| | >| case
| >| | >| enumDateTimeFormat.ShortDateFormat:
| >| | >|
| return
| >| | >| mDate.ToShortDateString();
| >| | >| case
| >| | >| enumDateTimeFormat.ShortTimeFormat:
| >| | >|
| return
| >| | >| mDate.ToShortTimeString();
| >| | >| default:
| >| | >|
| throw new
| >| | >| UnhandledDateFormatException(Format);
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Return the value of the
| object as a
| >| | >| ShortDateString.
| >| | >| /// </summary>
| >| | >| /// <returns></returns>
| >| | >| public string GetValue()
| >| | >| {
| >| | >| return GetValue
| >| | >| (enumDateTimeFormat.ShortDateFormat);
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Public Override Methods
| >| | >| /// <summary>
| >| | >| /// Passes a string containing
| the date
| >| | >| in <see
| cref="enumDateTimeFormat.ShortDateFormat"/>.
| >| | >| /// </summary>
| >| | >| /// <returns>The date returned.
| Passes an
| >| | >| empty string for blank (null) dates.</returns>
| >| | >| public override string ToString()
| >| | >| {
| >| | >| return GetValue();
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Properties
| >| | >| /// <summary>
| >| | >| /// Returns the date of the
| >| | >| OptionalDateTime as a DateTime type. Raises the
| >| | >| /// <see
| >| | >| cref="OptionalDateTimeIsNullException"/> if the
| >| | >| OptionalDateTime is
| >| | >| /// blank (null). Check the <see
| >| | >| cref="IsNull"/> property before calling this
| >| | >| /// method to avoid the exception.
| >| | >| /// </summary>
| >| | >| public DateTime GetDateTime
| >| | >| {
| >| | >| get
| >| | >| {
| >| | >| if(mIsNull)
| >| | >| {
| >| | >| throw new
| >| | >| OptionalDateTimeIsNullException();
| >| | >| }
| >| | >| return mDate;
| >| | >| }
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Gets a boolean value
| indicating
| >| | >| whether the OptionalDateTime is blank (null).
| >| | >| /// </summary>
| >| | >| public bool IsNull
| >| | >| {
| >| | >| get
| >| | >| {
| >| | >| return mIsNull;
| >| | >| }
| >| | >| }
| >| | >| #endregion
| >| | >| }
| >| | >|
| >| | >| thanks in advance
| >| | >|
| >| | >
| >| | >.
| >| | >
| >| |
| >|
| >
| >.
| >
|

Nov 15 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Terrance | last post by:
Good Afternoon: I was hoping if someone could share some light on a problem that I'm facing. When I create a Visual Basic.Net program and I use the XP style for my Window Forms and buttons; if I...
4
by: #ROBERT | last post by:
(VS 2003 + .NET Framework 1.1 + WinXP Pro SP2) Calling Application.EnableVisualStyles() after the initialization() removes all images in the tab control (in the tab headers I mean). Without...
4
by: Jacek Jurkowski | last post by:
.... the minimum date of DateTimePicker is 1753-01-01. How to make DateTime to do not show nothing in its text if this date is the value? I have a form with a field LastLogonDate. If user hasn't...
3
by: Charlie | last post by:
In the top portion of the DateTimePicker, where the value of the date is displayed, how can I detect whether the month or day or year is currently focused, or, if ShowCheckBox = True, whether the...
2
by: SiJP | last post by:
There is a lot of information out there that shows you how to use a manifest file with your .net application (exe) to enable windows xp styles. I am building a dll for COM interop, which...
0
by: thull | last post by:
I'm trying to modify an older VB6 program and use the DateTimePicker control to give the user the ability to display and modify the system date and time. The VB6 documentation says it is available...
1
by: =?Utf-8?B?UmF5IE1pdGNoZWxs?= | last post by:
Hello, I posted this about a month ago but didn't get any response, so I thought I'd rephrase it. I have a DateTimePicker set for Up/Down Time format (HH:mm:ss). The problem is that when I...
4
by: jehugaleahsa | last post by:
Hello: We were hoping to allow users to have DateTimePicker value null so that a unused date is stored on a Database. Does the control support this? I am pretty sure it doesn't. How would you...
2
by: Todd Carnes | last post by:
I am trying to write an app in C# that requires the user to enter a date from 4000 B.C.E to 4000 C.E. I tried to use the DateTimePicker Control to allow the user to enter the date, but it only...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.