473,740 Members | 6,250 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

bug using Application.Ena bleVisualStyles () 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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual styles
aswell. Below is my implementation of the extended
datetimepicker and also the new data type
(OptionalDateTi me) that is used for the value property...

#####LockableDa teTimePicker Source######### ##

using System;
using System.Collecti ons;
using System.Componen tModel;
using System.Drawing;
using System.Data;
using System.Windows. Forms;
using HCS.DataTypes;

namespace HCS.Generic.UI. Controls
{
/// <summary>
/// LockableDateTim ePicker is for selecting
dates. It manipulates the OptionalDateTim e
/// class to allow null dates to be handled.
/// </summary>
public class LockableDateTim ePicker :
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.Disp ose
();
}
}
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 InitializeCompo nent()
{
components = new
System.Componen tModel.Containe r();
}
#endregion

#region Fields

private System.Componen tModel.Containe r
components = null;
private bool mReadOnly;
private DateTime mDateTime;
private Color mBackColor;
private Color mLockedColor;
private bool mChecked;

#endregion

#region Events

public event OnReadOnlyChang edDelegate
OnReadOnlyChang ed;

#endregion

#region EventArgs and Delegates

public class OnReadOnlyChang edEventArgs :
EventArgs
{
private bool mReadOnly;

public OnReadOnlyChang edEventArgs
(bool ReadOnly)
{
mReadOnly = ReadOnly;
}
public bool ReadOnly
{
get
{
return mReadOnly;
}
}
}
public delegate void
OnReadOnlyChang edDelegate(obje ct sender,
OnReadOnlyChang edEventArgs e);

#endregion

#region Constructor

public LockableDateTim ePicker()
{
// This call is required by the
Windows.Forms Form Designer.
InitializeCompo nent();

mBackColor =
base.CalendarMo nthBackground;
mLockedColor =
base.CalendarMo nthBackground;

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

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

#endregion

#region Properties

[DesignerSeriali zationVisibilit y
(DesignerSerial izationVisibili ty.Visible)]
public bool ReadOnly
{
get
{
return mReadOnly;
}
set
{
if(value)
{

base.CalendarMo nthBackground = mLockedColor;
}
else
{

base.CalendarMo nthBackground = mBackColor;
}

mReadOnly = value;
if(OnReadOnlyCh anged !=
null)
{
OnReadOnlyChang ed
(this, new OnReadOnlyChang edEventArgs(val ue));
}
}
}

[DesignerSeriali zationVisibilit y
(DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
{
set
{
if(value.GetVal ue() == "")
{
base.Checked =
false;
}
else
{
base.Value =
DateTime.Parse( value.GetValue( ));
}

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

#region Public Overridden Events

protected override void OnValueChanged
(EventArgs eventargs)
{
base.OnValueCha nged (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(Opti onalDateTime
Value)
{
//Temporarily set the control to
not ReadOnly.
bool mTempReadOnly = mReadOnly;
if(mReadOnly)
{
mReadOnly = false;
}

if(Value.GetVal ue() == "")
{
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(Date Time Value)
{
Initialise(new OptionalDateTim e
(Value));
}
public void Initialise()
{
Initialise(new OptionalDateTim e
());
}
#endregion
}
}

##############O ptionalDateTime Source######### #

[Serializable()]
public class OptionalDateTim e
{
#region Enum
/// <summary>
/// Formats available - extend as
required, but remember to update <see cref="GetValue"/>.
/// </summary>
public enum enumDateTimeFor mat
{
/// <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
OptionalDateTim e
/// </summary>
public OptionalDateTim e()
{
mIsNull = true;
}
/// <summary>
/// Constructor - initialise an
OptionalDateTim e 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 OptionalDateTim e(string value)
{
SetValue(value) ;
}
/// <summary>
/// Constructor - initialise an
OptionalDateTim e to contain the value of a DateTime.
/// </summary>
/// <param name="value">A DateTime value
type.</param>
public OptionalDateTim e(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(DateTi me 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
ArgumentExcepti on("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">T he format to
return.</param>
/// <returns>A string containing the
correctly formatted date.</returns>
public string GetValue(enumDa teTimeFormat
Format)
{
if(mIsNull)
{
return "";
}
else
{
switch(Format)
{
case
enumDateTimeFor mat.LongDateFor mat:
return
mDate.ToLongDat eString();
case
enumDateTimeFor mat.LongTimeFor mat:
return
mDate.ToLongTim eString();
case
enumDateTimeFor mat.ShortDateFo rmat:
return
mDate.ToShortDa teString();
case
enumDateTimeFor mat.ShortTimeFo rmat:
return
mDate.ToShortTi meString();
default:
throw new
UnhandledDateFo rmatException(F ormat);
}
}
}
/// <summary>
/// Return the value of the object as a
ShortDateString .
/// </summary>
/// <returns></returns>
public string GetValue()
{
return GetValue
(enumDateTimeFo rmat.ShortDateF ormat);
}
#endregion

#region Public Override Methods
/// <summary>
/// Passes a string containing the date
in <see cref="enumDateT imeFormat.Short DateFormat"/>.
/// </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
OptionalDateTim e as a DateTime type. Raises the
/// <see
cref="OptionalD ateTimeIsNullEx ception"/> if the
OptionalDateTim e 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
OptionalDateTim eIsNullExceptio n();
}
return mDate;
}
}
/// <summary>
/// Gets a boolean value indicating
whether the OptionalDateTim e is blank (null).
/// </summary>
public bool IsNull
{
get
{
return mIsNull;
}
}
#endregion
}

thanks in advance
Nov 15 '05 #1
9 3973

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.Ena bleVisualStyles () 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/QOSWuDQUgjMGLnA w==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| Path: cpmsftngxa06.ph x.gbl
| Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.langua ges.csharp:1937 74
| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual styles
| aswell. Below is my implementation of the extended
| datetimepicker and also the new data type
| (OptionalDateTi me) that is used for the value property...
|
| #####LockableDa teTimePicker Source######### ##
|
| using System;
| using System.Collecti ons;
| using System.Componen tModel;
| using System.Drawing;
| using System.Data;
| using System.Windows. Forms;
| using HCS.DataTypes;
|
| namespace HCS.Generic.UI. Controls
| {
| /// <summary>
| /// LockableDateTim ePicker is for selecting
| dates. It manipulates the OptionalDateTim e
| /// class to allow null dates to be handled.
| /// </summary>
| public class LockableDateTim ePicker :
| 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.Disp ose
| ();
| }
| }
| 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 InitializeCompo nent()
| {
| components = new
| System.Componen tModel.Containe r();
| }
| #endregion
|
| #region Fields
|
| private System.Componen tModel.Containe r
| components = null;
| private bool mReadOnly;
| private DateTime mDateTime;
| private Color mBackColor;
| private Color mLockedColor;
| private bool mChecked;
|
| #endregion
|
| #region Events
|
| public event OnReadOnlyChang edDelegate
| OnReadOnlyChang ed;
|
| #endregion
|
| #region EventArgs and Delegates
|
| public class OnReadOnlyChang edEventArgs :
| EventArgs
| {
| private bool mReadOnly;
|
| public OnReadOnlyChang edEventArgs
| (bool ReadOnly)
| {
| mReadOnly = ReadOnly;
| }
| public bool ReadOnly
| {
| get
| {
| return mReadOnly;
| }
| }
| }
| public delegate void
| OnReadOnlyChang edDelegate(obje ct sender,
| OnReadOnlyChang edEventArgs e);
|
| #endregion
|
| #region Constructor
|
| public LockableDateTim ePicker()
| {
| // This call is required by the
| Windows.Forms Form Designer.
| InitializeCompo nent();
|
| mBackColor =
| base.CalendarMo nthBackground;
| mLockedColor =
| base.CalendarMo nthBackground;
|
| //Set defaults for this control
| base.Format =
| DateTimePickerF ormat.Short;
|
| //Make sure that our date backup
| is populated
| mDateTime = base.Value;
| mChecked = base.Checked;
| }
|
| #endregion
|
| #region Properties
|
| [DesignerSeriali zationVisibilit y
| (DesignerSerial izationVisibili ty.Visible)]
| public bool ReadOnly
| {
| get
| {
| return mReadOnly;
| }
| set
| {
| if(value)
| {
|
| base.CalendarMo nthBackground = mLockedColor;
| }
| else
| {
|
| base.CalendarMo nthBackground = mBackColor;
| }
|
| mReadOnly = value;
| if(OnReadOnlyCh anged !=
| null)
| {
| OnReadOnlyChang ed
| (this, new OnReadOnlyChang edEventArgs(val ue));
| }
| }
| }
|
| [DesignerSeriali zationVisibilit y
| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| {
| set
| {
| if(value.GetVal ue() == "")
| {
| base.Checked =
| false;
| }
| else
| {
| base.Value =
| DateTime.Parse( value.GetValue( ));
| }
|
| }
| get
| {
| if(base.Checked )
| {
| return new
| OptionalDateTim e(base.Value);
| }
| else
| {
| return new
| OptionalDateTim e();
| }
| }
| }
| #endregion
|
| #region Public Overridden Events
|
| protected override void OnValueChanged
| (EventArgs eventargs)
| {
| base.OnValueCha nged (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(Opti onalDateTime
| Value)
| {
| //Temporarily set the control to
| not ReadOnly.
| bool mTempReadOnly = mReadOnly;
| if(mReadOnly)
| {
| mReadOnly = false;
| }
|
| if(Value.GetVal ue() == "")
| {
| 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(Date Time Value)
| {
| Initialise(new OptionalDateTim e
| (Value));
| }
| public void Initialise()
| {
| Initialise(new OptionalDateTim e
| ());
| }
| #endregion
| }
| }
|
| ##############O ptionalDateTime Source######### #
|
| [Serializable()]
| public class OptionalDateTim e
| {
| #region Enum
| /// <summary>
| /// Formats available - extend as
| required, but remember to update <see cref="GetValue"/>.
| /// </summary>
| public enum enumDateTimeFor mat
| {
| /// <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
| OptionalDateTim e
| /// </summary>
| public OptionalDateTim e()
| {
| mIsNull = true;
| }
| /// <summary>
| /// Constructor - initialise an
| OptionalDateTim e 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 OptionalDateTim e(string value)
| {
| SetValue(value) ;
| }
| /// <summary>
| /// Constructor - initialise an
| OptionalDateTim e to contain the value of a DateTime.
| /// </summary>
| /// <param name="value">A DateTime value
| type.</param>
| public OptionalDateTim e(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(DateTi me 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
| ArgumentExcepti on("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">T he format to
| return.</param>
| /// <returns>A string containing the
| correctly formatted date.</returns>
| public string GetValue(enumDa teTimeFormat
| Format)
| {
| if(mIsNull)
| {
| return "";
| }
| else
| {
| switch(Format)
| {
| case
| enumDateTimeFor mat.LongDateFor mat:
| return
| mDate.ToLongDat eString();
| case
| enumDateTimeFor mat.LongTimeFor mat:
| return
| mDate.ToLongTim eString();
| case
| enumDateTimeFor mat.ShortDateFo rmat:
| return
| mDate.ToShortDa teString();
| case
| enumDateTimeFor mat.ShortTimeFo rmat:
| return
| mDate.ToShortTi meString();
| default:
| throw new
| UnhandledDateFo rmatException(F ormat);
| }
| }
| }
| /// <summary>
| /// Return the value of the object as a
| ShortDateString .
| /// </summary>
| /// <returns></returns>
| public string GetValue()
| {
| return GetValue
| (enumDateTimeFo rmat.ShortDateF ormat);
| }
| #endregion
|
| #region Public Override Methods
| /// <summary>
| /// Passes a string containing the date
| in <see cref="enumDateT imeFormat.Short DateFormat"/>.
| /// </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
| OptionalDateTim e as a DateTime type. Raises the
| /// <see
| cref="OptionalD ateTimeIsNullEx ception"/> if the
| OptionalDateTim e 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
| OptionalDateTim eIsNullExceptio n();
| }
| return mDate;
| }
| }
| /// <summary>
| /// Gets a boolean value indicating
| whether the OptionalDateTim e 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.Ena bleVisualStyles () 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/QOSWuDQUgjMGLnA w==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| Path: cpmsftngxa06.ph x.gbl
| Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.langua ges.csharp:1937 74| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual styles| aswell. Below is my implementation of the extended
| datetimepicker and also the new data type
| (OptionalDateTi me) that is used for the value property...|
| #####LockableDa teTimePicker Source######### ##
|
| using System;
| using System.Collecti ons;
| using System.Componen tModel;
| using System.Drawing;
| using System.Data;
| using System.Windows. Forms;
| using HCS.DataTypes;
|
| namespace HCS.Generic.UI. Controls
| {
| /// <summary>
| /// LockableDateTim ePicker is for selecting
| dates. It manipulates the OptionalDateTim e
| /// class to allow null dates to be handled.
| /// </summary>
| public class LockableDateTim ePicker :
| 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.Disp ose
| ();
| }
| }
| 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 InitializeCompo nent()
| {
| components = new
| System.Componen tModel.Containe r();
| }
| #endregion
|
| #region Fields
|
| private System.Componen tModel.Containe r
| components = null;
| private bool mReadOnly;
| private DateTime mDateTime;
| private Color mBackColor;
| private Color mLockedColor;
| private bool mChecked;
|
| #endregion
|
| #region Events
|
| public event OnReadOnlyChang edDelegate
| OnReadOnlyChang ed;
|
| #endregion
|
| #region EventArgs and Delegates
|
| public class OnReadOnlyChang edEventArgs :
| EventArgs
| {
| private bool mReadOnly;
|
| public OnReadOnlyChang edEventArgs
| (bool ReadOnly)
| {
| mReadOnly = ReadOnly;
| }
| public bool ReadOnly
| {
| get
| {
| return mReadOnly;
| }
| }
| }
| public delegate void
| OnReadOnlyChang edDelegate(obje ct sender,
| OnReadOnlyChang edEventArgs e);
|
| #endregion
|
| #region Constructor
|
| public LockableDateTim ePicker()
| {
| // This call is required by the
| Windows.Forms Form Designer.
| InitializeCompo nent();
|
| mBackColor =
| base.CalendarMo nthBackground;
| mLockedColor =
| base.CalendarMo nthBackground;
|
| //Set defaults for this control
| base.Format =
| DateTimePickerF ormat.Short;
|
| //Make sure that our date backup
| is populated
| mDateTime = base.Value;
| mChecked = base.Checked;
| }
|
| #endregion
|
| #region Properties
|
| [DesignerSeriali zationVisibilit y
| (DesignerSerial izationVisibili ty.Visible)]
| public bool ReadOnly
| {
| get
| {
| return mReadOnly;
| }
| set
| {
| if(value)
| {
|
| base.CalendarMo nthBackground = mLockedColor;
| }
| else
| {
|
| base.CalendarMo nthBackground = mBackColor;
| }
|
| mReadOnly = value;
| if(OnReadOnlyCh anged !=
| null)
| {
| OnReadOnlyChang ed
| (this, new OnReadOnlyChang edEventArgs(val ue));
| }
| }
| }
|
| [DesignerSeriali zationVisibilit y
| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| {
| set
| {
| if(value.GetVal ue() == "")
| {
| base.Checked =
| false;
| }
| else
| {
| base.Value =
| DateTime.Parse( value.GetValue( ));
| }
|
| }
| get
| {
| if(base.Checked )
| {
| return new
| OptionalDateTim e(base.Value);
| }
| else
| {
| return new
| OptionalDateTim e();
| }
| }
| }
| #endregion
|
| #region Public Overridden Events
|
| protected override void OnValueChanged
| (EventArgs eventargs)
| {
| base.OnValueCha nged (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(Opti onalDateTime
| Value)
| {
| //Temporarily set the control to
| not ReadOnly.
| bool mTempReadOnly = mReadOnly;
| if(mReadOnly)
| {
| mReadOnly = false;
| }
|
| if(Value.GetVal ue() == "")
| {
| 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(Date Time Value)
| {
| Initialise(new OptionalDateTim e
| (Value));
| }
| public void Initialise()
| {
| Initialise(new OptionalDateTim e
| ());
| }
| #endregion
| }
| }
|
| ##############O ptionalDateTime Source######### #
|
| [Serializable()]
| public class OptionalDateTim e
| {
| #region Enum
| /// <summary>
| /// Formats available - extend as
| required, but remember to update <see cref="GetValue"/>.| /// </summary>
| public enum enumDateTimeFor mat
| {
| /// <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
| OptionalDateTim e
| /// </summary>
| public OptionalDateTim e()
| {
| mIsNull = true;
| }
| /// <summary>
| /// Constructor - initialise an
| OptionalDateTim e 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 OptionalDateTim e(string value)
| {
| SetValue(value) ;
| }
| /// <summary>
| /// Constructor - initialise an
| OptionalDateTim e to contain the value of a DateTime.
| /// </summary>
| /// <param name="value">A DateTime value
| type.</param>
| public OptionalDateTim e(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(DateTi me 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
| ArgumentExcepti on("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">T he format to
| return.</param>
| /// <returns>A string containing the
| correctly formatted date.</returns>
| public string GetValue(enumDa teTimeFormat
| Format)
| {
| if(mIsNull)
| {
| return "";
| }
| else
| {
| switch(Format)
| {
| case
| enumDateTimeFor mat.LongDateFor mat:
| return
| mDate.ToLongDat eString();
| case
| enumDateTimeFor mat.LongTimeFor mat:
| return
| mDate.ToLongTim eString();
| case
| enumDateTimeFor mat.ShortDateFo rmat:
| return
| mDate.ToShortDa teString();
| case
| enumDateTimeFor mat.ShortTimeFo rmat:
| return
| mDate.ToShortTi meString();
| default:
| throw new
| UnhandledDateFo rmatException(F ormat);
| }
| }
| }
| /// <summary>
| /// Return the value of the object as a
| ShortDateString .
| /// </summary>
| /// <returns></returns>
| public string GetValue()
| {
| return GetValue
| (enumDateTimeFo rmat.ShortDateF ormat);
| }
| #endregion
|
| #region Public Override Methods
| /// <summary>
| /// Passes a string containing the date
| in <see cref="enumDateT imeFormat.Short DateFormat"/>.
| /// </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
| OptionalDateTim e as a DateTime type. Raises the
| /// <see
| cref="OptionalD ateTimeIsNullEx ception"/> if the
| OptionalDateTim e 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
| OptionalDateTim eIsNullExceptio n();
| }
| return mDate;
| }
| }
| /// <summary>
| /// Gets a boolean value indicating
| whether the OptionalDateTim e 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 .InteropService s ;
public bool readonlyval=fal se;
private DateTime oldval;

protected override void OnCloseUp(Event Args eventargs)
{
if(readonlyval= =true)
{
this.Value =oldval;
}
oldval=this.Val ue ;
base.OnCloseUp (eventargs);
}

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=M CN_FIRST + 1;
private int WM_NOTIFY=0x004 E;

[StructLayout(La youtKind.Sequen tial)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(m.Msg==WM_NO TIFY)
{
if(m.HWnd==this .Handle)
{
NMHDR nm1=(NMHDR)Mars hal.PtrToStruct ure(m.LParam,ty peof(NMHDR));
if(nm1.code==MC N_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\Inc lude 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.Ena bleVisualStyles () 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+yabmh BTea+z5L0ii9kXg ==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| Path: cpmsftngxa06.ph x.gbl
| Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.langua ges.csharp:1946 27
| NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles ()
| 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/QOSWuDQUgjMGLnA w==
| >| X-MimeOLE: Produced By Microsoft MimeOLE
| V5.50.4910.0300
| >| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| >| Path: cpmsftngxa06.ph x.gbl
| >| Xref: cpmsftngxa06.ph x.gbl
| microsoft.publi c.dotnet.langua ges.csharp:1937 74
| >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| >| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual
| styles
| >| aswell. Below is my implementation of the extended
| >| datetimepicker and also the new data type
| >| (OptionalDateTi me) that is used for the value
| property...
| >|
| >| #####LockableDa teTimePicker Source######### ##
| >|
| >| using System;
| >| using System.Collecti ons;
| >| using System.Componen tModel;
| >| using System.Drawing;
| >| using System.Data;
| >| using System.Windows. Forms;
| >| using HCS.DataTypes;
| >|
| >| namespace HCS.Generic.UI. Controls
| >| {
| >| /// <summary>
| >| /// LockableDateTim ePicker is for selecting
| >| dates. It manipulates the OptionalDateTim e
| >| /// class to allow null dates to be handled.
| >| /// </summary>
| >| public class LockableDateTim ePicker :
| >| 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.Disp ose
| >| ();
| >| }
| >| }
| >| 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 InitializeCompo nent()
| >| {
| >| components = new
| >| System.Componen tModel.Containe r();
| >| }
| >| #endregion
| >|
| >| #region Fields
| >|
| >| private System.Componen tModel.Containe r
| >| components = null;
| >| private bool mReadOnly;
| >| private DateTime mDateTime;
| >| private Color mBackColor;
| >| private Color mLockedColor;
| >| private bool mChecked;
| >|
| >| #endregion
| >|
| >| #region Events
| >|
| >| public event OnReadOnlyChang edDelegate
| >| OnReadOnlyChang ed;
| >|
| >| #endregion
| >|
| >| #region EventArgs and Delegates
| >|
| >| public class OnReadOnlyChang edEventArgs :
| >| EventArgs
| >| {
| >| private bool mReadOnly;
| >|
| >| public OnReadOnlyChang edEventArgs
| >| (bool ReadOnly)
| >| {
| >| mReadOnly = ReadOnly;
| >| }
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| }
| >| }
| >| public delegate void
| >| OnReadOnlyChang edDelegate(obje ct sender,
| >| OnReadOnlyChang edEventArgs e);
| >|
| >| #endregion
| >|
| >| #region Constructor
| >|
| >| public LockableDateTim ePicker()
| >| {
| >| // This call is required by the
| >| Windows.Forms Form Designer.
| >| InitializeCompo nent();
| >|
| >| mBackColor =
| >| base.CalendarMo nthBackground;
| >| mLockedColor =
| >| base.CalendarMo nthBackground;
| >|
| >| //Set defaults for this control
| >| base.Format =
| >| DateTimePickerF ormat.Short;
| >|
| >| //Make sure that our date backup
| >| is populated
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >|
| >| #endregion
| >|
| >| #region Properties
| >|
| >| [DesignerSeriali zationVisibilit y
| >| (DesignerSerial izationVisibili ty.Visible)]
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| set
| >| {
| >| if(value)
| >| {
| >|
| >| base.CalendarMo nthBackground = mLockedColor;
| >| }
| >| else
| >| {
| >|
| >| base.CalendarMo nthBackground = mBackColor;
| >| }
| >|
| >| mReadOnly = value;
| >| if(OnReadOnlyCh anged !=
| >| null)
| >| {
| >| OnReadOnlyChang ed
| >| (this, new OnReadOnlyChang edEventArgs(val ue));
| >| }
| >| }
| >| }
| >|
| >| [DesignerSeriali zationVisibilit y
| >| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| >| {
| >| set
| >| {
| >| if(value.GetVal ue() == "")
| >| {
| >| base.Checked =
| >| false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse( value.GetValue( ));
| >| }
| >|
| >| }
| >| get
| >| {
| >| if(base.Checked )
| >| {
| >| return new
| >| OptionalDateTim e(base.Value);
| >| }
| >| else
| >| {
| >| return new
| >| OptionalDateTim e();
| >| }
| >| }
| >| }
| >| #endregion
| >|
| >| #region Public Overridden Events
| >|
| >| protected override void OnValueChanged
| >| (EventArgs eventargs)
| >| {
| >| base.OnValueCha nged (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(Opti onalDateTime
| >| Value)
| >| {
| >| //Temporarily set the control to
| >| not ReadOnly.
| >| bool mTempReadOnly = mReadOnly;
| >| if(mReadOnly)
| >| {
| >| mReadOnly = false;
| >| }
| >|
| >| if(Value.GetVal ue() == "")
| >| {
| >| 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(Date Time Value)
| >| {
| >| Initialise(new OptionalDateTim e
| >| (Value));
| >| }
| >| public void Initialise()
| >| {
| >| Initialise(new OptionalDateTim e
| >| ());
| >| }
| >| #endregion
| >| }
| >| }
| >|
| >| ##############O ptionalDateTime Source######### #
| >|
| >| [Serializable()]
| >| public class OptionalDateTim e
| >| {
| >| #region Enum
| >| /// <summary>
| >| /// Formats available - extend as
| >| required, but remember to update <see
| cref="GetValue"/>.
| >| /// </summary>
| >| public enum enumDateTimeFor mat
| >| {
| >| /// <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
| >| OptionalDateTim e
| >| /// </summary>
| >| public OptionalDateTim e()
| >| {
| >| mIsNull = true;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTim e 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 OptionalDateTim e(string value)
| >| {
| >| SetValue(value) ;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTim e to contain the value of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A DateTime value
| >| type.</param>
| >| public OptionalDateTim e(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(DateTi me 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
| >| ArgumentExcepti on("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">T he format to
| >| return.</param>
| >| /// <returns>A string containing the
| >| correctly formatted date.</returns>
| >| public string GetValue(enumDa teTimeFormat
| >| Format)
| >| {
| >| if(mIsNull)
| >| {
| >| return "";
| >| }
| >| else
| >| {
| >| switch(Format)
| >| {
| >| case
| >| enumDateTimeFor mat.LongDateFor mat:
| >| return
| >| mDate.ToLongDat eString();
| >| case
| >| enumDateTimeFor mat.LongTimeFor mat:
| >| return
| >| mDate.ToLongTim eString();
| >| case
| >| enumDateTimeFor mat.ShortDateFo rmat:
| >| return
| >| mDate.ToShortDa teString();
| >| case
| >| enumDateTimeFor mat.ShortTimeFo rmat:
| >| return
| >| mDate.ToShortTi meString();
| >| default:
| >| throw new
| >| UnhandledDateFo rmatException(F ormat);
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| ShortDateString .
| >| /// </summary>
| >| /// <returns></returns>
| >| public string GetValue()
| >| {
| >| return GetValue
| >| (enumDateTimeFo rmat.ShortDateF ormat);
| >| }
| >| #endregion
| >|
| >| #region Public Override Methods
| >| /// <summary>
| >| /// Passes a string containing the date
| >| in <see cref="enumDateT imeFormat.Short DateFormat"/>.
| >| /// </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
| >| OptionalDateTim e as a DateTime type. Raises the
| >| /// <see
| >| cref="OptionalD ateTimeIsNullEx ception"/> if the
| >| OptionalDateTim e 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
| >| OptionalDateTim eIsNullExceptio n();
| >| }
| >| return mDate;
| >| }
| >| }
| >| /// <summary>
| >| /// Gets a boolean value indicating
| >| whether the OptionalDateTim e 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.Va lue ;" 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.publi c.dotnet.langua ges.csharp
| From: v-*****@online.mi crosoft.com ("Jeffrey Tan[MSFT]")
| Organization: Microsoft
| Date: Wed, 29 Oct 2003 03:12:29 GMT
| Subject: RE: bug using Application.Ena bleVisualStyles () with
datetimepicker control
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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 .InteropService s ;
| public bool readonlyval=fal se;
| private DateTime oldval;
|
| protected override void OnCloseUp(Event Args eventargs)
| {
| if(readonlyval= =true)
| {
| this.Value =oldval;
| }
| oldval=this.Val ue ;
| base.OnCloseUp (eventargs);
| }
|
| private const int MCN_FIRST=-750;
| private const int MCN_SELCHANGE=M CN_FIRST + 1;
| private int WM_NOTIFY=0x004 E;
|
| [StructLayout(La youtKind.Sequen tial)]
| public struct NMHDR
| {
| public IntPtr hwndFrom;
| public int idfrom;
| public int code;
| }
|
| protected override void WndProc(ref Message m)
| {
| if(m.Msg==WM_NO TIFY)
| {
| if(m.HWnd==this .Handle)
| {
| NMHDR nm1=(NMHDR)Mars hal.PtrToStruct ure(m.LParam,ty peof(NMHDR));
| if(nm1.code==MC N_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\Inc lude 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.Ena bleVisualStyles () 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+yabmh BTea+z5L0ii9kXg ==
| | X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| | Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| | Path: cpmsftngxa06.ph x.gbl
| | Xref: cpmsftngxa06.ph x.gbl
microsoft.publi c.dotnet.langua ges.csharp:1946 27
| | NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| | X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles ()
| | 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/QOSWuDQUgjMGLnA w==
| | >| X-MimeOLE: Produced By Microsoft MimeOLE
| | V5.50.4910.0300
| | >| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| | >| Path: cpmsftngxa06.ph x.gbl
| | >| Xref: cpmsftngxa06.ph x.gbl
| | microsoft.publi c.dotnet.langua ges.csharp:1937 74
| | >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| | >| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual
| | styles
| | >| aswell. Below is my implementation of the extended
| | >| datetimepicker and also the new data type
| | >| (OptionalDateTi me) that is used for the value
| | property...
| | >|
| | >| #####LockableDa teTimePicker Source######### ##
| | >|
| | >| using System;
| | >| using System.Collecti ons;
| | >| using System.Componen tModel;
| | >| using System.Drawing;
| | >| using System.Data;
| | >| using System.Windows. Forms;
| | >| using HCS.DataTypes;
| | >|
| | >| namespace HCS.Generic.UI. Controls
| | >| {
| | >| /// <summary>
| | >| /// LockableDateTim ePicker is for selecting
| | >| dates. It manipulates the OptionalDateTim e
| | >| /// class to allow null dates to be handled.
| | >| /// </summary>
| | >| public class LockableDateTim ePicker :
| | >| 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.Disp ose
| | >| ();
| | >| }
| | >| }
| | >| 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 InitializeCompo nent()
| | >| {
| | >| components = new
| | >| System.Componen tModel.Containe r();
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >|
| | >| private System.Componen tModel.Containe r
| | >| components = null;
| | >| private bool mReadOnly;
| | >| private DateTime mDateTime;
| | >| private Color mBackColor;
| | >| private Color mLockedColor;
| | >| private bool mChecked;
| | >|
| | >| #endregion
| | >|
| | >| #region Events
| | >|
| | >| public event OnReadOnlyChang edDelegate
| | >| OnReadOnlyChang ed;
| | >|
| | >| #endregion
| | >|
| | >| #region EventArgs and Delegates
| | >|
| | >| public class OnReadOnlyChang edEventArgs :
| | >| EventArgs
| | >| {
| | >| private bool mReadOnly;
| | >|
| | >| public OnReadOnlyChang edEventArgs
| | >| (bool ReadOnly)
| | >| {
| | >| mReadOnly = ReadOnly;
| | >| }
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| }
| | >| }
| | >| public delegate void
| | >| OnReadOnlyChang edDelegate(obje ct sender,
| | >| OnReadOnlyChang edEventArgs e);
| | >|
| | >| #endregion
| | >|
| | >| #region Constructor
| | >|
| | >| public LockableDateTim ePicker()
| | >| {
| | >| // This call is required by the
| | >| Windows.Forms Form Designer.
| | >| InitializeCompo nent();
| | >|
| | >| mBackColor =
| | >| base.CalendarMo nthBackground;
| | >| mLockedColor =
| | >| base.CalendarMo nthBackground;
| | >|
| | >| //Set defaults for this control
| | >| base.Format =
| | >| DateTimePickerF ormat.Short;
| | >|
| | >| //Make sure that our date backup
| | >| is populated
| | >| mDateTime = base.Value;
| | >| mChecked = base.Checked;
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Properties
| | >|
| | >| [DesignerSeriali zationVisibilit y
| | >| (DesignerSerial izationVisibili ty.Visible)]
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| set
| | >| {
| | >| if(value)
| | >| {
| | >|
| | >| base.CalendarMo nthBackground = mLockedColor;
| | >| }
| | >| else
| | >| {
| | >|
| | >| base.CalendarMo nthBackground = mBackColor;
| | >| }
| | >|
| | >| mReadOnly = value;
| | >| if(OnReadOnlyCh anged !=
| | >| null)
| | >| {
| | >| OnReadOnlyChang ed
| | >| (this, new OnReadOnlyChang edEventArgs(val ue));
| | >| }
| | >| }
| | >| }
| | >|
| | >| [DesignerSeriali zationVisibilit y
| | >| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| | >| {
| | >| set
| | >| {
| | >| if(value.GetVal ue() == "")
| | >| {
| | >| base.Checked =
| | >| false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =
| | >| DateTime.Parse( value.GetValue( ));
| | >| }
| | >|
| | >| }
| | >| get
| | >| {
| | >| if(base.Checked )
| | >| {
| | >| return new
| | >| OptionalDateTim e(base.Value);
| | >| }
| | >| else
| | >| {
| | >| return new
| | >| OptionalDateTim e();
| | >| }
| | >| }
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Overridden Events
| | >|
| | >| protected override void OnValueChanged
| | >| (EventArgs eventargs)
| | >| {
| | >| base.OnValueCha nged (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(Opti onalDateTime
| | >| Value)
| | >| {
| | >| //Temporarily set the control to
| | >| not ReadOnly.
| | >| bool mTempReadOnly = mReadOnly;
| | >| if(mReadOnly)
| | >| {
| | >| mReadOnly = false;
| | >| }
| | >|
| | >| if(Value.GetVal ue() == "")
| | >| {
| | >| 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(Date Time Value)
| | >| {
| | >| Initialise(new OptionalDateTim e
| | >| (Value));
| | >| }
| | >| public void Initialise()
| | >| {
| | >| Initialise(new OptionalDateTim e
| | >| ());
| | >| }
| | >| #endregion
| | >| }
| | >| }
| | >|
| | >| ##############O ptionalDateTime Source######### #
| | >|
| | >| [Serializable()]
| | >| public class OptionalDateTim e
| | >| {
| | >| #region Enum
| | >| /// <summary>
| | >| /// Formats available - extend as
| | >| required, but remember to update <see
| | cref="GetValue"/>.
| | >| /// </summary>
| | >| public enum enumDateTimeFor mat
| | >| {
| | >| /// <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
| | >| OptionalDateTim e
| | >| /// </summary>
| | >| public OptionalDateTim e()
| | >| {
| | >| mIsNull = true;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTim e 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 OptionalDateTim e(string value)
| | >| {
| | >| SetValue(value) ;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTim e to contain the value of a DateTime.
| | >| /// </summary>
| | >| /// <param name="value">A DateTime value
| | >| type.</param>
| | >| public OptionalDateTim e(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(DateTi me 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
| | >| ArgumentExcepti on("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">T he format to
| | >| return.</param>
| | >| /// <returns>A string containing the
| | >| correctly formatted date.</returns>
| | >| public string GetValue(enumDa teTimeFormat
| | >| Format)
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| return "";
| | >| }
| | >| else
| | >| {
| | >| switch(Format)
| | >| {
| | >| case
| | >| enumDateTimeFor mat.LongDateFor mat:
| | >| return
| | >| mDate.ToLongDat eString();
| | >| case
| | >| enumDateTimeFor mat.LongTimeFor mat:
| | >| return
| | >| mDate.ToLongTim eString();
| | >| case
| | >| enumDateTimeFor mat.ShortDateFo rmat:
| | >| return
| | >| mDate.ToShortDa teString();
| | >| case
| | >| enumDateTimeFor mat.ShortTimeFo rmat:
| | >| return
| | >| mDate.ToShortTi meString();
| | >| default:
| | >| throw new
| | >| UnhandledDateFo rmatException(F ormat);
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a
| | >| ShortDateString .
| | >| /// </summary>
| | >| /// <returns></returns>
| | >| public string GetValue()
| | >| {
| | >| return GetValue
| | >| (enumDateTimeFo rmat.ShortDateF ormat);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Override Methods
| | >| /// <summary>
| | >| /// Passes a string containing the date
| | >| in <see cref="enumDateT imeFormat.Short DateFormat"/>.
| | >| /// </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
| | >| OptionalDateTim e as a DateTime type. Raises the
| | >| /// <see
| | >| cref="OptionalD ateTimeIsNullEx ception"/> if the
| | >| OptionalDateTim e 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
| | >| OptionalDateTim eIsNullExceptio n();
| | >| }
| | >| return mDate;
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Gets a boolean value indicating
| | >| whether the OptionalDateTim e 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 .InteropService s ;
public bool readonlyval=fal se;
private DateTime oldval;

oldval=this.Val ue; // in this control's constructor

protected override void OnCloseUp(Event Args eventargs)
{
if(readonlyval= =true)
{
this.Value =oldval;
}
oldval=this.Val ue ;
base.OnCloseUp (eventargs);
}

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=M CN_FIRST + 1;
private int WM_NOTIFY=0x004 E;

[StructLayout(La youtKind.Sequen tial)]
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_NO TIFY)
{
if(m.HWnd==this .Handle)
{
NMHDR nm1=(NMHDR)Mars hal.PtrToStruct ure(m.LParam,ty peof(NMHDR));
if(nm1.code==MC N_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\Inc lude 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.Ena bleVisualStyles () 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+yabmh BTea+z5L0ii9kXg ==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| Path: cpmsftngxa06.ph x.gbl
| Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.langua ges.csharp:1946 27
| NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles ()
| 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/QOSWuDQUgjMGLnA w==
| >| X-MimeOLE: Produced By Microsoft MimeOLE
| V5.50.4910.0300
| >| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| >| Path: cpmsftngxa06.ph x.gbl
| >| Xref: cpmsftngxa06.ph x.gbl
| microsoft.publi c.dotnet.langua ges.csharp:1937 74
| >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| >| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual
| styles
| >| aswell. Below is my implementation of the extended
| >| datetimepicker and also the new data type
| >| (OptionalDateTi me) that is used for the value
| property...
| >|
| >| #####LockableDa teTimePicker Source######### ##
| >|
| >| using System;
| >| using System.Collecti ons;
| >| using System.Componen tModel;
| >| using System.Drawing;
| >| using System.Data;
| >| using System.Windows. Forms;
| >| using HCS.DataTypes;
| >|
| >| namespace HCS.Generic.UI. Controls
| >| {
| >| /// <summary>
| >| /// LockableDateTim ePicker is for selecting
| >| dates. It manipulates the OptionalDateTim e
| >| /// class to allow null dates to be handled.
| >| /// </summary>
| >| public class LockableDateTim ePicker :
| >| 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.Disp ose
| >| ();
| >| }
| >| }
| >| 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 InitializeCompo nent()
| >| {
| >| components = new
| >| System.Componen tModel.Containe r();
| >| }
| >| #endregion
| >|
| >| #region Fields
| >|
| >| private System.Componen tModel.Containe r
| >| components = null;
| >| private bool mReadOnly;
| >| private DateTime mDateTime;
| >| private Color mBackColor;
| >| private Color mLockedColor;
| >| private bool mChecked;
| >|
| >| #endregion
| >|
| >| #region Events
| >|
| >| public event OnReadOnlyChang edDelegate
| >| OnReadOnlyChang ed;
| >|
| >| #endregion
| >|
| >| #region EventArgs and Delegates
| >|
| >| public class OnReadOnlyChang edEventArgs :
| >| EventArgs
| >| {
| >| private bool mReadOnly;
| >|
| >| public OnReadOnlyChang edEventArgs
| >| (bool ReadOnly)
| >| {
| >| mReadOnly = ReadOnly;
| >| }
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| }
| >| }
| >| public delegate void
| >| OnReadOnlyChang edDelegate(obje ct sender,
| >| OnReadOnlyChang edEventArgs e);
| >|
| >| #endregion
| >|
| >| #region Constructor
| >|
| >| public LockableDateTim ePicker()
| >| {
| >| // This call is required by the
| >| Windows.Forms Form Designer.
| >| InitializeCompo nent();
| >|
| >| mBackColor =
| >| base.CalendarMo nthBackground;
| >| mLockedColor =
| >| base.CalendarMo nthBackground;
| >|
| >| //Set defaults for this control
| >| base.Format =
| >| DateTimePickerF ormat.Short;
| >|
| >| //Make sure that our date backup
| >| is populated
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >|
| >| #endregion
| >|
| >| #region Properties
| >|
| >| [DesignerSeriali zationVisibilit y
| >| (DesignerSerial izationVisibili ty.Visible)]
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| set
| >| {
| >| if(value)
| >| {
| >|
| >| base.CalendarMo nthBackground = mLockedColor;
| >| }
| >| else
| >| {
| >|
| >| base.CalendarMo nthBackground = mBackColor;
| >| }
| >|
| >| mReadOnly = value;
| >| if(OnReadOnlyCh anged !=
| >| null)
| >| {
| >| OnReadOnlyChang ed
| >| (this, new OnReadOnlyChang edEventArgs(val ue));
| >| }
| >| }
| >| }
| >|
| >| [DesignerSeriali zationVisibilit y
| >| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| >| {
| >| set
| >| {
| >| if(value.GetVal ue() == "")
| >| {
| >| base.Checked =
| >| false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse( value.GetValue( ));
| >| }
| >|
| >| }
| >| get
| >| {
| >| if(base.Checked )
| >| {
| >| return new
| >| OptionalDateTim e(base.Value);
| >| }
| >| else
| >| {
| >| return new
| >| OptionalDateTim e();
| >| }
| >| }
| >| }
| >| #endregion
| >|
| >| #region Public Overridden Events
| >|
| >| protected override void OnValueChanged
| >| (EventArgs eventargs)
| >| {
| >| base.OnValueCha nged (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(Opti onalDateTime
| >| Value)
| >| {
| >| //Temporarily set the control to
| >| not ReadOnly.
| >| bool mTempReadOnly = mReadOnly;
| >| if(mReadOnly)
| >| {
| >| mReadOnly = false;
| >| }
| >|
| >| if(Value.GetVal ue() == "")
| >| {
| >| 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(Date Time Value)
| >| {
| >| Initialise(new OptionalDateTim e
| >| (Value));
| >| }
| >| public void Initialise()
| >| {
| >| Initialise(new OptionalDateTim e
| >| ());
| >| }
| >| #endregion
| >| }
| >| }
| >|
| >| ##############O ptionalDateTime Source######### #
| >|
| >| [Serializable()]
| >| public class OptionalDateTim e
| >| {
| >| #region Enum
| >| /// <summary>
| >| /// Formats available - extend as
| >| required, but remember to update <see
| cref="GetValue"/>.
| >| /// </summary>
| >| public enum enumDateTimeFor mat
| >| {
| >| /// <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
| >| OptionalDateTim e
| >| /// </summary>
| >| public OptionalDateTim e()
| >| {
| >| mIsNull = true;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTim e 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 OptionalDateTim e(string value)
| >| {
| >| SetValue(value) ;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTim e to contain the value of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A DateTime value
| >| type.</param>
| >| public OptionalDateTim e(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(DateTi me 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
| >| ArgumentExcepti on("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">T he format to
| >| return.</param>
| >| /// <returns>A string containing the
| >| correctly formatted date.</returns>
| >| public string GetValue(enumDa teTimeFormat
| >| Format)
| >| {
| >| if(mIsNull)
| >| {
| >| return "";
| >| }
| >| else
| >| {
| >| switch(Format)
| >| {
| >| case
| >| enumDateTimeFor mat.LongDateFor mat:
| >| return
| >| mDate.ToLongDat eString();
| >| case
| >| enumDateTimeFor mat.LongTimeFor mat:
| >| return
| >| mDate.ToLongTim eString();
| >| case
| >| enumDateTimeFor mat.ShortDateFo rmat:
| >| return
| >| mDate.ToShortDa teString();
| >| case
| >| enumDateTimeFor mat.ShortTimeFo rmat:
| >| return
| >| mDate.ToShortTi meString();
| >| default:
| >| throw new
| >| UnhandledDateFo rmatException(F ormat);
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| ShortDateString .
| >| /// </summary>
| >| /// <returns></returns>
| >| public string GetValue()
| >| {
| >| return GetValue
| >| (enumDateTimeFo rmat.ShortDateF ormat);
| >| }
| >| #endregion
| >|
| >| #region Public Override Methods
| >| /// <summary>
| >| /// Passes a string containing the date
| >| in <see cref="enumDateT imeFormat.Short DateFormat"/>.
| >| /// </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
| >| OptionalDateTim e as a DateTime type. Raises the
| >| /// <see
| >| cref="OptionalD ateTimeIsNullEx ception"/> if the
| >| OptionalDateTim e 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
| >| OptionalDateTim eIsNullExceptio n();
| >| }
| >| return mDate;
| >| }
| >| }
| >| /// <summary>
| >| /// Gets a boolean value indicating
| >| whether the OptionalDateTim e 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 .InteropService s ;
public bool readonlyval=fal se;
private DateTime oldval;

oldval=this.Val ue; // in this control's constructor

protected override void OnCloseUp(Event Args eventargs)
{
if(readonlyval= =true)
{
this.Value =oldval;
}
oldval=this.Val ue ;
base.OnCloseUp (eventargs);
}

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=M CN_FIRST + 1;
private int WM_NOTIFY=0x004 E;

[StructLayout(La youtKind.Sequen tial)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(this.readonl yval==true)
{
if(m.Msg==WM_NO TIFY)
{
if(m.HWnd==this .Handle)
{
NMHDR nm1=(NMHDR)Mars hal.PtrToStruct ure(m.LParam,ty peof(NMHDR));
if(nm1.code==MC N_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\Inc lude 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.Ena bleVisualStyles () 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+yabmh BTea+z5L0ii9kXg ==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| Path: cpmsftngxa06.ph x.gbl
| Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.langua ges.csharp:1946 27
| NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles ()
| 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/QOSWuDQUgjMGLnA w==
| >| X-MimeOLE: Produced By Microsoft MimeOLE
| V5.50.4910.0300
| >| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| >| Path: cpmsftngxa06.ph x.gbl
| >| Xref: cpmsftngxa06.ph x.gbl
| microsoft.publi c.dotnet.langua ges.csharp:1937 74
| >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| >| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual
| styles
| >| aswell. Below is my implementation of the extended
| >| datetimepicker and also the new data type
| >| (OptionalDateTi me) that is used for the value
| property...
| >|
| >| #####LockableDa teTimePicker Source######### ##
| >|
| >| using System;
| >| using System.Collecti ons;
| >| using System.Componen tModel;
| >| using System.Drawing;
| >| using System.Data;
| >| using System.Windows. Forms;
| >| using HCS.DataTypes;
| >|
| >| namespace HCS.Generic.UI. Controls
| >| {
| >| /// <summary>
| >| /// LockableDateTim ePicker is for selecting
| >| dates. It manipulates the OptionalDateTim e
| >| /// class to allow null dates to be handled.
| >| /// </summary>
| >| public class LockableDateTim ePicker :
| >| 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.Disp ose
| >| ();
| >| }
| >| }
| >| 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 InitializeCompo nent()
| >| {
| >| components = new
| >| System.Componen tModel.Containe r();
| >| }
| >| #endregion
| >|
| >| #region Fields
| >|
| >| private System.Componen tModel.Containe r
| >| components = null;
| >| private bool mReadOnly;
| >| private DateTime mDateTime;
| >| private Color mBackColor;
| >| private Color mLockedColor;
| >| private bool mChecked;
| >|
| >| #endregion
| >|
| >| #region Events
| >|
| >| public event OnReadOnlyChang edDelegate
| >| OnReadOnlyChang ed;
| >|
| >| #endregion
| >|
| >| #region EventArgs and Delegates
| >|
| >| public class OnReadOnlyChang edEventArgs :
| >| EventArgs
| >| {
| >| private bool mReadOnly;
| >|
| >| public OnReadOnlyChang edEventArgs
| >| (bool ReadOnly)
| >| {
| >| mReadOnly = ReadOnly;
| >| }
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| }
| >| }
| >| public delegate void
| >| OnReadOnlyChang edDelegate(obje ct sender,
| >| OnReadOnlyChang edEventArgs e);
| >|
| >| #endregion
| >|
| >| #region Constructor
| >|
| >| public LockableDateTim ePicker()
| >| {
| >| // This call is required by the
| >| Windows.Forms Form Designer.
| >| InitializeCompo nent();
| >|
| >| mBackColor =
| >| base.CalendarMo nthBackground;
| >| mLockedColor =
| >| base.CalendarMo nthBackground;
| >|
| >| //Set defaults for this control
| >| base.Format =
| >| DateTimePickerF ormat.Short;
| >|
| >| //Make sure that our date backup
| >| is populated
| >| mDateTime = base.Value;
| >| mChecked = base.Checked;
| >| }
| >|
| >| #endregion
| >|
| >| #region Properties
| >|
| >| [DesignerSeriali zationVisibilit y
| >| (DesignerSerial izationVisibili ty.Visible)]
| >| public bool ReadOnly
| >| {
| >| get
| >| {
| >| return mReadOnly;
| >| }
| >| set
| >| {
| >| if(value)
| >| {
| >|
| >| base.CalendarMo nthBackground = mLockedColor;
| >| }
| >| else
| >| {
| >|
| >| base.CalendarMo nthBackground = mBackColor;
| >| }
| >|
| >| mReadOnly = value;
| >| if(OnReadOnlyCh anged !=
| >| null)
| >| {
| >| OnReadOnlyChang ed
| >| (this, new OnReadOnlyChang edEventArgs(val ue));
| >| }
| >| }
| >| }
| >|
| >| [DesignerSeriali zationVisibilit y
| >| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| >| {
| >| set
| >| {
| >| if(value.GetVal ue() == "")
| >| {
| >| base.Checked =
| >| false;
| >| }
| >| else
| >| {
| >| base.Value =
| >| DateTime.Parse( value.GetValue( ));
| >| }
| >|
| >| }
| >| get
| >| {
| >| if(base.Checked )
| >| {
| >| return new
| >| OptionalDateTim e(base.Value);
| >| }
| >| else
| >| {
| >| return new
| >| OptionalDateTim e();
| >| }
| >| }
| >| }
| >| #endregion
| >|
| >| #region Public Overridden Events
| >|
| >| protected override void OnValueChanged
| >| (EventArgs eventargs)
| >| {
| >| base.OnValueCha nged (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(Opti onalDateTime
| >| Value)
| >| {
| >| //Temporarily set the control to
| >| not ReadOnly.
| >| bool mTempReadOnly = mReadOnly;
| >| if(mReadOnly)
| >| {
| >| mReadOnly = false;
| >| }
| >|
| >| if(Value.GetVal ue() == "")
| >| {
| >| 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(Date Time Value)
| >| {
| >| Initialise(new OptionalDateTim e
| >| (Value));
| >| }
| >| public void Initialise()
| >| {
| >| Initialise(new OptionalDateTim e
| >| ());
| >| }
| >| #endregion
| >| }
| >| }
| >|
| >| ##############O ptionalDateTime Source######### #
| >|
| >| [Serializable()]
| >| public class OptionalDateTim e
| >| {
| >| #region Enum
| >| /// <summary>
| >| /// Formats available - extend as
| >| required, but remember to update <see
| cref="GetValue"/>.
| >| /// </summary>
| >| public enum enumDateTimeFor mat
| >| {
| >| /// <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
| >| OptionalDateTim e
| >| /// </summary>
| >| public OptionalDateTim e()
| >| {
| >| mIsNull = true;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTim e 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 OptionalDateTim e(string value)
| >| {
| >| SetValue(value) ;
| >| }
| >| /// <summary>
| >| /// Constructor - initialise an
| >| OptionalDateTim e to contain the value of a DateTime.
| >| /// </summary>
| >| /// <param name="value">A DateTime value
| >| type.</param>
| >| public OptionalDateTim e(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(DateTi me 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
| >| ArgumentExcepti on("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">T he format to
| >| return.</param>
| >| /// <returns>A string containing the
| >| correctly formatted date.</returns>
| >| public string GetValue(enumDa teTimeFormat
| >| Format)
| >| {
| >| if(mIsNull)
| >| {
| >| return "";
| >| }
| >| else
| >| {
| >| switch(Format)
| >| {
| >| case
| >| enumDateTimeFor mat.LongDateFor mat:
| >| return
| >| mDate.ToLongDat eString();
| >| case
| >| enumDateTimeFor mat.LongTimeFor mat:
| >| return
| >| mDate.ToLongTim eString();
| >| case
| >| enumDateTimeFor mat.ShortDateFo rmat:
| >| return
| >| mDate.ToShortDa teString();
| >| case
| >| enumDateTimeFor mat.ShortTimeFo rmat:
| >| return
| >| mDate.ToShortTi meString();
| >| default:
| >| throw new
| >| UnhandledDateFo rmatException(F ormat);
| >| }
| >| }
| >| }
| >| /// <summary>
| >| /// Return the value of the object as a
| >| ShortDateString .
| >| /// </summary>
| >| /// <returns></returns>
| >| public string GetValue()
| >| {
| >| return GetValue
| >| (enumDateTimeFo rmat.ShortDateF ormat);
| >| }
| >| #endregion
| >|
| >| #region Public Override Methods
| >| /// <summary>
| >| /// Passes a string containing the date
| >| in <see cref="enumDateT imeFormat.Short DateFormat"/>.
| >| /// </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
| >| OptionalDateTim e as a DateTime type. Raises the
| >| /// <see
| >| cref="OptionalD ateTimeIsNullEx ception"/> if the
| >| OptionalDateTim e 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
| >| OptionalDateTim eIsNullExceptio n();
| >| }
| >| return mDate;
| >| }
| >| }
| >| /// <summary>
| >| /// Gets a boolean value indicating
| >| whether the OptionalDateTim e 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_RELEASECAPTU RE, 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 .InteropService s ;

public bool readonlyval=fal se;
private DateTime oldval;

oldval=this.Val ue ; // in control's constructor

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=M CN_FIRST + 1;
private const int MCN_SELECT=MCN_ FIRST + 4;
private int WM_NOTIFY=0x004 E;

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

[DllImport("user 32.dll")]
public static extern bool DestroyWindow(I ntPtr hwnd);

[StructLayout(La youtKind.Sequen tial)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(this.readonl yval==true)
{
if(m.Msg==WM_NO TIFY)
{
if(m.HWnd==this .Handle)
{
NMHDR nm1=(NMHDR)Mars hal.PtrToStruct ure(m.LParam,ty peof(NMHDR));
if(nm1.code==MC N_SELCHANGE)
{
return;
}
if(nm1.code ==MCN_SELECT)
{
IntPtr calendarhandle= FindWindowEx(In tPtr.Zero ,IntPtr.Zero
,"SysMonthCal32 ",String.Empty) ;
DestroyWindow(c alendarhandle);
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.publi c.dotnet.langua ges.csharp
| From: v-*****@online.mi crosoft.com ("Jeffrey Tan[MSFT]")
| Organization: Microsoft
| Date: Wed, 29 Oct 2003 03:46:45 GMT
| Subject: RE: bug using Application.Ena bleVisualStyles () with
datetimepicker control
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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 .InteropService s ;
| public bool readonlyval=fal se;
| private DateTime oldval;
|
| oldval=this.Val ue; // in this control's constructor
|
| protected override void OnCloseUp(Event Args eventargs)
| {
| if(readonlyval= =true)
| {
| this.Value =oldval;
| }
| oldval=this.Val ue ;
| base.OnCloseUp (eventargs);
| }
|
| private const int MCN_FIRST=-750;
| private const int MCN_SELCHANGE=M CN_FIRST + 1;
| private int WM_NOTIFY=0x004 E;
|
| [StructLayout(La youtKind.Sequen tial)]
| public struct NMHDR
| {
| public IntPtr hwndFrom;
| public int idfrom;
| public int code;
| }
|
| protected override void WndProc(ref Message m)
| {
| if(this.readonl yval==true)
| {
| if(m.Msg==WM_NO TIFY)
| {
| if(m.HWnd==this .Handle)
| {
| NMHDR nm1=(NMHDR)Mars hal.PtrToStruct ure(m.LParam,ty peof(NMHDR));
| if(nm1.code==MC N_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\Inc lude 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.Ena bleVisualStyles () 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+yabmh BTea+z5L0ii9kXg ==
| | X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| | Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| | Path: cpmsftngxa06.ph x.gbl
| | Xref: cpmsftngxa06.ph x.gbl
microsoft.publi c.dotnet.langua ges.csharp:1946 27
| | NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| | X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles ()
| | 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/QOSWuDQUgjMGLnA w==
| | >| X-MimeOLE: Produced By Microsoft MimeOLE
| | V5.50.4910.0300
| | >| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| | >| Path: cpmsftngxa06.ph x.gbl
| | >| Xref: cpmsftngxa06.ph x.gbl
| | microsoft.publi c.dotnet.langua ges.csharp:1937 74
| | >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| | >| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual
| | styles
| | >| aswell. Below is my implementation of the extended
| | >| datetimepicker and also the new data type
| | >| (OptionalDateTi me) that is used for the value
| | property...
| | >|
| | >| #####LockableDa teTimePicker Source######### ##
| | >|
| | >| using System;
| | >| using System.Collecti ons;
| | >| using System.Componen tModel;
| | >| using System.Drawing;
| | >| using System.Data;
| | >| using System.Windows. Forms;
| | >| using HCS.DataTypes;
| | >|
| | >| namespace HCS.Generic.UI. Controls
| | >| {
| | >| /// <summary>
| | >| /// LockableDateTim ePicker is for selecting
| | >| dates. It manipulates the OptionalDateTim e
| | >| /// class to allow null dates to be handled.
| | >| /// </summary>
| | >| public class LockableDateTim ePicker :
| | >| 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.Disp ose
| | >| ();
| | >| }
| | >| }
| | >| 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 InitializeCompo nent()
| | >| {
| | >| components = new
| | >| System.Componen tModel.Containe r();
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >|
| | >| private System.Componen tModel.Containe r
| | >| components = null;
| | >| private bool mReadOnly;
| | >| private DateTime mDateTime;
| | >| private Color mBackColor;
| | >| private Color mLockedColor;
| | >| private bool mChecked;
| | >|
| | >| #endregion
| | >|
| | >| #region Events
| | >|
| | >| public event OnReadOnlyChang edDelegate
| | >| OnReadOnlyChang ed;
| | >|
| | >| #endregion
| | >|
| | >| #region EventArgs and Delegates
| | >|
| | >| public class OnReadOnlyChang edEventArgs :
| | >| EventArgs
| | >| {
| | >| private bool mReadOnly;
| | >|
| | >| public OnReadOnlyChang edEventArgs
| | >| (bool ReadOnly)
| | >| {
| | >| mReadOnly = ReadOnly;
| | >| }
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| }
| | >| }
| | >| public delegate void
| | >| OnReadOnlyChang edDelegate(obje ct sender,
| | >| OnReadOnlyChang edEventArgs e);
| | >|
| | >| #endregion
| | >|
| | >| #region Constructor
| | >|
| | >| public LockableDateTim ePicker()
| | >| {
| | >| // This call is required by the
| | >| Windows.Forms Form Designer.
| | >| InitializeCompo nent();
| | >|
| | >| mBackColor =
| | >| base.CalendarMo nthBackground;
| | >| mLockedColor =
| | >| base.CalendarMo nthBackground;
| | >|
| | >| //Set defaults for this control
| | >| base.Format =
| | >| DateTimePickerF ormat.Short;
| | >|
| | >| //Make sure that our date backup
| | >| is populated
| | >| mDateTime = base.Value;
| | >| mChecked = base.Checked;
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Properties
| | >|
| | >| [DesignerSeriali zationVisibilit y
| | >| (DesignerSerial izationVisibili ty.Visible)]
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| set
| | >| {
| | >| if(value)
| | >| {
| | >|
| | >| base.CalendarMo nthBackground = mLockedColor;
| | >| }
| | >| else
| | >| {
| | >|
| | >| base.CalendarMo nthBackground = mBackColor;
| | >| }
| | >|
| | >| mReadOnly = value;
| | >| if(OnReadOnlyCh anged !=
| | >| null)
| | >| {
| | >| OnReadOnlyChang ed
| | >| (this, new OnReadOnlyChang edEventArgs(val ue));
| | >| }
| | >| }
| | >| }
| | >|
| | >| [DesignerSeriali zationVisibilit y
| | >| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| | >| {
| | >| set
| | >| {
| | >| if(value.GetVal ue() == "")
| | >| {
| | >| base.Checked =
| | >| false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =
| | >| DateTime.Parse( value.GetValue( ));
| | >| }
| | >|
| | >| }
| | >| get
| | >| {
| | >| if(base.Checked )
| | >| {
| | >| return new
| | >| OptionalDateTim e(base.Value);
| | >| }
| | >| else
| | >| {
| | >| return new
| | >| OptionalDateTim e();
| | >| }
| | >| }
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Overridden Events
| | >|
| | >| protected override void OnValueChanged
| | >| (EventArgs eventargs)
| | >| {
| | >| base.OnValueCha nged (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(Opti onalDateTime
| | >| Value)
| | >| {
| | >| //Temporarily set the control to
| | >| not ReadOnly.
| | >| bool mTempReadOnly = mReadOnly;
| | >| if(mReadOnly)
| | >| {
| | >| mReadOnly = false;
| | >| }
| | >|
| | >| if(Value.GetVal ue() == "")
| | >| {
| | >| 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(Date Time Value)
| | >| {
| | >| Initialise(new OptionalDateTim e
| | >| (Value));
| | >| }
| | >| public void Initialise()
| | >| {
| | >| Initialise(new OptionalDateTim e
| | >| ());
| | >| }
| | >| #endregion
| | >| }
| | >| }
| | >|
| | >| ##############O ptionalDateTime Source######### #
| | >|
| | >| [Serializable()]
| | >| public class OptionalDateTim e
| | >| {
| | >| #region Enum
| | >| /// <summary>
| | >| /// Formats available - extend as
| | >| required, but remember to update <see
| | cref="GetValue"/>.
| | >| /// </summary>
| | >| public enum enumDateTimeFor mat
| | >| {
| | >| /// <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
| | >| OptionalDateTim e
| | >| /// </summary>
| | >| public OptionalDateTim e()
| | >| {
| | >| mIsNull = true;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTim e 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 OptionalDateTim e(string value)
| | >| {
| | >| SetValue(value) ;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTim e to contain the value of a DateTime.
| | >| /// </summary>
| | >| /// <param name="value">A DateTime value
| | >| type.</param>
| | >| public OptionalDateTim e(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(DateTi me 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
| | >| ArgumentExcepti on("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">T he format to
| | >| return.</param>
| | >| /// <returns>A string containing the
| | >| correctly formatted date.</returns>
| | >| public string GetValue(enumDa teTimeFormat
| | >| Format)
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| return "";
| | >| }
| | >| else
| | >| {
| | >| switch(Format)
| | >| {
| | >| case
| | >| enumDateTimeFor mat.LongDateFor mat:
| | >| return
| | >| mDate.ToLongDat eString();
| | >| case
| | >| enumDateTimeFor mat.LongTimeFor mat:
| | >| return
| | >| mDate.ToLongTim eString();
| | >| case
| | >| enumDateTimeFor mat.ShortDateFo rmat:
| | >| return
| | >| mDate.ToShortDa teString();
| | >| case
| | >| enumDateTimeFor mat.ShortTimeFo rmat:
| | >| return
| | >| mDate.ToShortTi meString();
| | >| default:
| | >| throw new
| | >| UnhandledDateFo rmatException(F ormat);
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a
| | >| ShortDateString .
| | >| /// </summary>
| | >| /// <returns></returns>
| | >| public string GetValue()
| | >| {
| | >| return GetValue
| | >| (enumDateTimeFo rmat.ShortDateF ormat);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Override Methods
| | >| /// <summary>
| | >| /// Passes a string containing the date
| | >| in <see cref="enumDateT imeFormat.Short DateFormat"/>.
| | >| /// </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
| | >| OptionalDateTim e as a DateTime type. Raises the
| | >| /// <see
| | >| cref="OptionalD ateTimeIsNullEx ception"/> if the
| | >| OptionalDateTim e 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
| | >| OptionalDateTim eIsNullExceptio n();
| | >| }
| | >| return mDate;
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Gets a boolean value indicating
| | >| whether the OptionalDateTim e 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_RELEASECAPTU RE, 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 .InteropService s ;

public bool readonlyval=fal se;
private DateTime oldval;

oldval=this.Va lue ; // in control's constructor

private const int MCN_FIRST=-750;
private const int MCN_SELCHANGE=M CN_FIRST + 1;
private const int MCN_SELECT=MCN_ FIRST + 4;
private int WM_NOTIFY=0x004 E;

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

[DllImport("user 32.dll")]
public static extern bool DestroyWindow(I ntPtr hwnd);

[StructLayout(La youtKind.Sequen tial)]
public struct NMHDR
{
public IntPtr hwndFrom;
public int idfrom;
public int code;
}

protected override void WndProc(ref Message m)
{
if(this.readonl yval==true)
{
if(m.Msg==WM_NO TIFY)
{
if(m.HWnd==this .Handle)
{
NMHDR nm1=(NMHDR) Marshal.PtrToSt ructure(m.LPara m,typeof(NMHDR) ); if (nm1.code==MCN_ SELCHANGE) {
return;
}
if(nm1.code ==MCN_SELECT)
{
IntPtr calendarhandle= FindWindowEx(In tPtr.Zero ,IntPtr.Zero,"SysMonthCal3 2",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.publi c.dotnet.langua ges.csharp
| From: v-*****@online.mi crosoft.com ("Jeffrey Tan [MSFT]")| Organization: Microsoft
| Date: Wed, 29 Oct 2003 03:46:45 GMT
| Subject: RE: bug using Application.Ena bleVisualStyles () withdatetimepick er control
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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 .InteropService s ;
| public bool readonlyval=fal se;
| private DateTime oldval;
|
| oldval=this.Val ue; // in this control's constructor
|
| protected override void OnCloseUp(Event Args eventargs)
| {
| if(readonlyval= =true)
| {
| this.Value =oldval;
| }
| oldval=this.Val ue ;
| base.OnCloseUp (eventargs);
| }
|
| private const int MCN_FIRST=-750;
| private const int MCN_SELCHANGE=M CN_FIRST + 1;
| private int WM_NOTIFY=0x004 E;
|
| [StructLayout(La youtKind.Sequen tial)]
| public struct NMHDR
| {
| public IntPtr hwndFrom;
| public int idfrom;
| public int code;
| }
|
| protected override void WndProc(ref Message m)
| {
| if(this.readonl yval==true)
| {
| if(m.Msg==WM_NO TIFY)
| {
| if(m.HWnd==this .Handle)
| {
| NMHDR nm1=(NMHDR) Marshal.PtrToSt ructure(m.LPara m,typeof(NMHDR) );| if(nm1.code==MC N_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\Inc lude 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.Ena bleVisualStyles () 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+yabmh BTea+z5L0ii9kXg ==
| | X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300| | Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| | Path: cpmsftngxa06.ph x.gbl
| | Xref: cpmsftngxa06.ph x.gbl
microsoft.publ ic.dotnet.langu ages.csharp:194 627
| | NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| | X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles ()| | with datetimepicker
| | >control
| | >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| | >| Lines: 540
| | >| Message-ID: <085401c39a1d$7 c2d0480 $a*******@phx.g bl>| | >| 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/QOSWuDQUgjMGLnA w==
| | >| X-MimeOLE: Produced By Microsoft MimeOLE
| | V5.50.4910.0300
| | >| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp| | >| Path: cpmsftngxa06.ph x.gbl
| | >| Xref: cpmsftngxa06.ph x.gbl
| | microsoft.publi c.dotnet.langua ges.csharp:1937 74
| | >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| | >| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual
| | styles
| | >| aswell. Below is my implementation of the extended| | >| datetimepicker and also the new data type
| | >| (OptionalDateTi me) that is used for the value
| | property...
| | >|
| | >| #####LockableDa teTimePicker Source######### ##
| | >|
| | >| using System;
| | >| using System.Collecti ons;
| | >| using System.Componen tModel;
| | >| using System.Drawing;
| | >| using System.Data;
| | >| using System.Windows. Forms;
| | >| using HCS.DataTypes;
| | >|
| | >| namespace HCS.Generic.UI. Controls
| | >| {
| | >| /// <summary>
| | >| /// LockableDateTim ePicker is for selecting| | >| dates. It manipulates the OptionalDateTim e
| | >| /// class to allow null dates to be handled.| | >| /// </summary>
| | >| public class LockableDateTim ePicker :
| | >| 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.Disp ose| | >| ();
| | >| }
| | >| }
| | >| 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 InitializeCompo nent()
| | >| {
| | >| components = new
| | >| System.Componen tModel.Containe r();
| | >| }
| | >| #endregion
| | >|
| | >| #region Fields
| | >|
| | >| private System.Componen tModel.Containe r| | >| components = null;
| | >| private bool mReadOnly;
| | >| private DateTime mDateTime;
| | >| private Color mBackColor;
| | >| private Color mLockedColor;
| | >| private bool mChecked;
| | >|
| | >| #endregion
| | >|
| | >| #region Events
| | >|
| | >| public event OnReadOnlyChang edDelegate| | >| OnReadOnlyChang ed;
| | >|
| | >| #endregion
| | >|
| | >| #region EventArgs and Delegates
| | >|
| | >| public class OnReadOnlyChang edEventArgs :| | >| EventArgs
| | >| {
| | >| private bool mReadOnly;
| | >|
| | >| public OnReadOnlyChang edEventArgs| | >| (bool ReadOnly)
| | >| {
| | >| mReadOnly = ReadOnly;| | >| }
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;| | >| }
| | >| }
| | >| }
| | >| public delegate void
| | >| OnReadOnlyChang edDelegate(obje ct sender,
| | >| OnReadOnlyChang edEventArgs e);
| | >|
| | >| #endregion
| | >|
| | >| #region Constructor
| | >|
| | >| public LockableDateTim ePicker()
| | >| {
| | >| // This call is required by the| | >| Windows.Forms Form Designer.
| | >| InitializeCompo nent();
| | >|
| | >| mBackColor =
| | >| base.CalendarMo nthBackground;
| | >| mLockedColor =
| | >| base.CalendarMo nthBackground;
| | >|
| | >| //Set defaults for this control| | >| base.Format =
| | >| DateTimePickerF ormat.Short;
| | >|
| | >| //Make sure that our date backup| | >| is populated
| | >| mDateTime = base.Value;
| | >| mChecked = base.Checked;
| | >| }
| | >|
| | >| #endregion
| | >|
| | >| #region Properties
| | >|
| | >| [DesignerSeriali zationVisibilit y
| | >| (DesignerSerial izationVisibili ty.Visible)]
| | >| public bool ReadOnly
| | >| {
| | >| get
| | >| {
| | >| return mReadOnly;
| | >| }
| | >| set
| | >| {
| | >| if(value)
| | >| {
| | >|
| | >| base.CalendarMo nthBackground = mLockedColor;| | >| }
| | >| else
| | >| {
| | >|
| | >| base.CalendarMo nthBackground = mBackColor;
| | >| }
| | >|
| | >| mReadOnly = value;
| | >| if (OnReadOnlyChan ged !=| | >| null)
| | >| {
| | >| OnReadOnlyChang ed| | >| (this, new OnReadOnlyChang edEventArgs(val ue));
| | >| }
| | >| }
| | >| }
| | >|
| | >| [DesignerSeriali zationVisibilit y
| | >| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| | >| {
| | >| set
| | >| {
| | >| if(value.GetVal ue () == "")| | >| {
| | >| base.Checked =| | >| false;
| | >| }
| | >| else
| | >| {
| | >| base.Value =| | >| DateTime.Parse( value.GetValue( ));
| | >| }
| | >|
| | >| }
| | >| get
| | >| {
| | >| if(base.Checked )
| | >| {
| | >| return new| | >| OptionalDateTim e(base.Value);
| | >| }
| | >| else
| | >| {
| | >| return new| | >| OptionalDateTim e();
| | >| }
| | >| }
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Overridden Events
| | >|
| | >| protected override void OnValueChanged| | >| (EventArgs eventargs)
| | >| {
| | >| base.OnValueCha nged (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 (OptionalDateTi me| | >| Value)
| | >| {
| | >| //Temporarily set the control to| | >| not ReadOnly.
| | >| bool mTempReadOnly = mReadOnly;| | >| if(mReadOnly)
| | >| {
| | >| mReadOnly = false;
| | >| }
| | >|
| | >| if(Value.GetVal ue() == "")
| | >| {
| | >| 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(Date Time Value)| | >| {
| | >| Initialise(new OptionalDateTim e| | >| (Value));
| | >| }
| | >| public void Initialise()
| | >| {
| | >| Initialise(new OptionalDateTim e| | >| ());
| | >| }
| | >| #endregion
| | >| }
| | >| }
| | >|
| | >| ##############O ptionalDateTime Source######### #
| | >|
| | >| [Serializable()]
| | >| public class OptionalDateTim e
| | >| {
| | >| #region Enum
| | >| /// <summary>
| | >| /// Formats available - extend as
| | >| required, but remember to update <see
| | cref="GetValue"/>.
| | >| /// </summary>
| | >| public enum enumDateTimeFor mat
| | >| {
| | >| /// <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| | >| OptionalDateTim e
| | >| /// </summary>
| | >| public OptionalDateTim e()
| | >| {
| | >| mIsNull = true;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTim e 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 OptionalDateTim e(string value)| | >| {
| | >| SetValue(value) ;
| | >| }
| | >| /// <summary>
| | >| /// Constructor - initialise an
| | >| OptionalDateTim e to contain the value of a DateTime.| | >| /// </summary>
| | >| /// <param name="value">A DateTime value| | >| type.</param>
| | >| public OptionalDateTim e(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(DateTi me 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
| | >| ArgumentExcepti on("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">T he format to| | >| return.</param>
| | >| /// <returns>A string containing the| | >| correctly formatted date.</returns>
| | >| public string GetValue (enumDateTimeFo rmat| | >| Format)
| | >| {
| | >| if(mIsNull)
| | >| {
| | >| return "";
| | >| }
| | >| else
| | >| {
| | >| switch(Format)
| | >| {
| | >| case
| | >| enumDateTimeFor mat.LongDateFor mat:
| | >| return| | >| mDate.ToLongDat eString();
| | >| case
| | >| enumDateTimeFor mat.LongTimeFor mat:
| | >| return| | >| mDate.ToLongTim eString();
| | >| case
| | >| enumDateTimeFor mat.ShortDateFo rmat:
| | >| return| | >| mDate.ToShortDa teString();
| | >| case
| | >| enumDateTimeFor mat.ShortTimeFo rmat:
| | >| return| | >| mDate.ToShortTi meString();
| | >| default:
| | >| throw new| | >| UnhandledDateFo rmatException(F ormat);
| | >| }
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Return the value of the object as a| | >| ShortDateString .
| | >| /// </summary>
| | >| /// <returns></returns>
| | >| public string GetValue()
| | >| {
| | >| return GetValue
| | >| (enumDateTimeFo rmat.ShortDateF ormat);
| | >| }
| | >| #endregion
| | >|
| | >| #region Public Override Methods
| | >| /// <summary>
| | >| /// Passes a string containing the date| | >| in <see cref="enumDateT imeFormat.Short DateFormat"/>.| | >| /// </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
| | >| OptionalDateTim e as a DateTime type. Raises the
| | >| /// <see
| | >| cref="OptionalD ateTimeIsNullEx ception"/> if the
| | >| OptionalDateTim e 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
| | >| OptionalDateTim eIsNullExceptio n();
| | >| }
| | >| return mDate;
| | >| }
| | >| }
| | >| /// <summary>
| | >| /// Gets a boolean value indicating| | >| whether the OptionalDateTim e 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.Ena bleVisualStyles () 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: AcOeMN0MVnak9Mh tTgyiX4kq1GG8Qw ==
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| Path: cpmsftngxa06.ph x.gbl
| Xref: cpmsftngxa06.ph x.gbl microsoft.publi c.dotnet.langua ges.csharp:1950 79
| NNTP-Posting-Host: TK2MSFTNGXA09 10.40.1.161
| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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_RELEASECAPTU RE,
| 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 .InteropService s ;
| >
| >public bool readonlyval=fal se;
| >private DateTime oldval;
| >
| >oldval=this.Va lue ; // in control's constructor
| >
| >private const int MCN_FIRST=-750;
| >private const int MCN_SELCHANGE=M CN_FIRST + 1;
| >private const int MCN_SELECT=MCN_ FIRST + 4;
| >private int WM_NOTIFY=0x004 E;
| >
| >[DllImport("user 32.dll")]
| >public static extern IntPtr FindWindowEx(In tPtr
| hWnd1,IntPtr
| >hWnd2,string lpsz1,string lpsz2);
| >
| >[DllImport("user 32.dll")]
| >public static extern bool DestroyWindow(I ntPtr hwnd);
| >
| >[StructLayout(La youtKind.Sequen tial)]
| > public struct NMHDR
| >{
| > public IntPtr hwndFrom;
| > public int idfrom;
| > public int code;
| >}
| >
| >protected override void WndProc(ref Message m)
| >{
| > if(this.readonl yval==true)
| > {
| > if(m.Msg==WM_NO TIFY)
| > {
| > if(m.HWnd==this .Handle)
| > {
| > NMHDR nm1=(NMHDR)
| Marshal.PtrToSt ructure(m.LPara m,typeof(NMHDR) );
| > if
| (nm1.code==MCN_ SELCHANGE)
| > {
| > return;
| > }
| > if(nm1.code ==MCN_SELECT)
| > {
| > IntPtr
| calendarhandle= FindWindowEx(In tPtr.Zero ,IntPtr.Zero
| >,"SysMonthCal3 2",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.publi c.dotnet.langua ges.csharp
| >| From: v-*****@online.mi crosoft.com ("Jeffrey Tan
| [MSFT]")
| >| Organization: Microsoft
| >| Date: Wed, 29 Oct 2003 03:46:45 GMT
| >| Subject: RE: bug using Application.Ena bleVisualStyles
| () with
| >datetimepick er control
| >| X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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 .InteropService s ;
| >| public bool readonlyval=fal se;
| >| private DateTime oldval;
| >|
| >| oldval=this.Val ue; // in this control's constructor
| >|
| >| protected override void OnCloseUp(Event Args eventargs)
| >| {
| >| if(readonlyval= =true)
| >| {
| >| this.Value =oldval;
| >| }
| >| oldval=this.Val ue ;
| >| base.OnCloseUp (eventargs);
| >| }
| >|
| >| private const int MCN_FIRST=-750;
| >| private const int MCN_SELCHANGE=M CN_FIRST + 1;
| >| private int WM_NOTIFY=0x004 E;
| >|
| >| [StructLayout(La youtKind.Sequen tial)]
| >| public struct NMHDR
| >| {
| >| public IntPtr hwndFrom;
| >| public int idfrom;
| >| public int code;
| >| }
| >|
| >| protected override void WndProc(ref Message m)
| >| {
| >| if(this.readonl yval==true)
| >| {
| >| if(m.Msg==WM_NO TIFY)
| >| {
| >| if(m.HWnd==this .Handle)
| >| {
| >| NMHDR nm1=(NMHDR)
| Marshal.PtrToSt ructure(m.LPara m,typeof(NMHDR) );
| >| if(nm1.code==MC N_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\Inc lude 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.Ena bleVisualStyles
| () 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+yabmh BTea+z5L0ii9kXg ==
| >| | X-MimeOLE: Produced By Microsoft MimeOLE
| V5.50.4910.0300
| >| | Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
| >| | Path: cpmsftngxa06.ph x.gbl
| >| | Xref: cpmsftngxa06.ph x.gbl
| >microsoft.publ ic.dotnet.langu ages.csharp:194 627
| >| | NNTP-Posting-Host: TK2MSFTNGXA14 10.40.1.166
| >| | X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles
| ()
| >| | with datetimepicker
| >| | >control
| >| | >| Date: Fri, 24 Oct 2003 03:56:32 -0700
| >| | >| Lines: 540
| >| | >| Message-ID: <085401c39a1d$7 c2d0480
| $a*******@phx.g bl>
| >| | >| 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/QOSWuDQUgjMGLnA w==
| >| | >| X-MimeOLE: Produced By Microsoft MimeOLE
| >| | V5.50.4910.0300
| >| | >| Newsgroups:
| microsoft.publi c.dotnet.langua ges.csharp
| >| | >| Path: cpmsftngxa06.ph x.gbl
| >| | >| Xref: cpmsftngxa06.ph x.gbl
| >| | microsoft.publi c.dotnet.langua ges.csharp:1937 74
| >| | >| NNTP-Posting-Host: TK2MSFTNGXA13 10.40.1.165
| >| | >| X-Tomcat-NG:
| microsoft.publi c.dotnet.langua ges.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.Ena bleVisualStyles () 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.textalign ment property when using XP Visual
| >| | styles
| >| | >| aswell. Below is my implementation of the
| extended
| >| | >| datetimepicker and also the new data type
| >| | >| (OptionalDateTi me) that is used for the value
| >| | property...
| >| | >|
| >| | >| #####LockableDa teTimePicker Source######### ##
| >| | >|
| >| | >| using System;
| >| | >| using System.Collecti ons;
| >| | >| using System.Componen tModel;
| >| | >| using System.Drawing;
| >| | >| using System.Data;
| >| | >| using System.Windows. Forms;
| >| | >| using HCS.DataTypes;
| >| | >|
| >| | >| namespace HCS.Generic.UI. Controls
| >| | >| {
| >| | >| /// <summary>
| >| | >| /// LockableDateTim ePicker is for
| selecting
| >| | >| dates. It manipulates the OptionalDateTim e
| >| | >| /// class to allow null dates to be
| handled.
| >| | >| /// </summary>
| >| | >| public class LockableDateTim ePicker :
| >| | >| 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.Disp ose
| >| | >| ();
| >| | >| }
| >| | >| }
| >| | >| 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 InitializeCompo nent()
| >| | >| {
| >| | >| components = new
| >| | >| System.Componen tModel.Containe r();
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Fields
| >| | >|
| >| | >| private
| System.Componen tModel.Containe r
| >| | >| components = null;
| >| | >| private bool mReadOnly;
| >| | >| private DateTime mDateTime;
| >| | >| private Color mBackColor;
| >| | >| private Color mLockedColor;
| >| | >| private bool mChecked;
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Events
| >| | >|
| >| | >| public event
| OnReadOnlyChang edDelegate
| >| | >| OnReadOnlyChang ed;
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region EventArgs and Delegates
| >| | >|
| >| | >| public class
| OnReadOnlyChang edEventArgs :
| >| | >| EventArgs
| >| | >| {
| >| | >| private bool mReadOnly;
| >| | >|
| >| | >| public
| OnReadOnlyChang edEventArgs
| >| | >| (bool ReadOnly)
| >| | >| {
| >| | >| mReadOnly =
| ReadOnly;
| >| | >| }
| >| | >| public bool ReadOnly
| >| | >| {
| >| | >| get
| >| | >| {
| >| | >| return
| mReadOnly;
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >| public delegate void
| >| | >| OnReadOnlyChang edDelegate(obje ct sender,
| >| | >| OnReadOnlyChang edEventArgs e);
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Constructor
| >| | >|
| >| | >| public LockableDateTim ePicker()
| >| | >| {
| >| | >| // This call is required
| by the
| >| | >| Windows.Forms Form Designer.
| >| | >| InitializeCompo nent();
| >| | >|
| >| | >| mBackColor =
| >| | >| base.CalendarMo nthBackground;
| >| | >| mLockedColor =
| >| | >| base.CalendarMo nthBackground;
| >| | >|
| >| | >| //Set defaults for this
| control
| >| | >| base.Format =
| >| | >| DateTimePickerF ormat.Short;
| >| | >|
| >| | >| //Make sure that our date
| backup
| >| | >| is populated
| >| | >| mDateTime = base.Value;
| >| | >| mChecked = base.Checked;
| >| | >| }
| >| | >|
| >| | >| #endregion
| >| | >|
| >| | >| #region Properties
| >| | >|
| >| | >| [DesignerSeriali zationVisibilit y
| >| | >| (DesignerSerial izationVisibili ty.Visible)]
| >| | >| public bool ReadOnly
| >| | >| {
| >| | >| get
| >| | >| {
| >| | >| return mReadOnly;
| >| | >| }
| >| | >| set
| >| | >| {
| >| | >| if(value)
| >| | >| {
| >| | >|
| >| | >| base.CalendarMo nthBackground =
| mLockedColor;
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >|
| >| | >| base.CalendarMo nthBackground = mBackColor;
| >| | >| }
| >| | >|
| >| | >| mReadOnly = value;
| >| | >| if
| (OnReadOnlyChan ged !=
| >| | >| null)
| >| | >| {
| >| | >|
| OnReadOnlyChang ed
| >| | >| (this, new OnReadOnlyChang edEventArgs(val ue));
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >|
| >| | >| [DesignerSeriali zationVisibilit y
| >| | >| (DesignerSerial izationVisibili ty.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 OptionalDateTim e Value
| >| | >| {
| >| | >| set
| >| | >| {
| >| | >| if(value.GetVal ue
| () == "")
| >| | >| {
| >| | >|
| base.Checked =
| >| | >| false;
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >|
| base.Value =
| >| | >| DateTime.Parse( value.GetValue( ));
| >| | >| }
| >| | >|
| >| | >| }
| >| | >| get
| >| | >| {
| >| | >| if(base.Checked )
| >| | >| {
| >| | >| return
| new
| >| | >| OptionalDateTim e(base.Value);
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >| return
| new
| >| | >| OptionalDateTim e();
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Public Overridden Events
| >| | >|
| >| | >| protected override void
| OnValueChanged
| >| | >| (EventArgs eventargs)
| >| | >| {
| >| | >| base.OnValueCha nged
| (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
| (OptionalDateTi me
| >| | >| Value)
| >| | >| {
| >| | >| //Temporarily set the
| control to
| >| | >| not ReadOnly.
| >| | >| bool mTempReadOnly =
| mReadOnly;
| >| | >| if(mReadOnly)
| >| | >| {
| >| | >| mReadOnly = false;
| >| | >| }
| >| | >|
| >| | >| if(Value.GetVal ue() == "")
| >| | >| {
| >| | >| 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(Date Time
| Value)
| >| | >| {
| >| | >| Initialise(new
| OptionalDateTim e
| >| | >| (Value));
| >| | >| }
| >| | >| public void Initialise()
| >| | >| {
| >| | >| Initialise(new
| OptionalDateTim e
| >| | >| ());
| >| | >| }
| >| | >| #endregion
| >| | >| }
| >| | >| }
| >| | >|
| >| | >| ##############O ptionalDateTime Source######### #
| >| | >|
| >| | >| [Serializable()]
| >| | >| public class OptionalDateTim e
| >| | >| {
| >| | >| #region Enum
| >| | >| /// <summary>
| >| | >| /// Formats available - extend as
| >| | >| required, but remember to update <see
| >| | cref="GetValue"/>.
| >| | >| /// </summary>
| >| | >| public enum enumDateTimeFor mat
| >| | >| {
| >| | >| /// <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
| >| | >| OptionalDateTim e
| >| | >| /// </summary>
| >| | >| public OptionalDateTim e()
| >| | >| {
| >| | >| mIsNull = true;
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Constructor - initialise an
| >| | >| OptionalDateTim e 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 OptionalDateTim e(string
| value)
| >| | >| {
| >| | >| SetValue(value) ;
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Constructor - initialise an
| >| | >| OptionalDateTim e to contain the value of a
| DateTime.
| >| | >| /// </summary>
| >| | >| /// <param name="value">A
| DateTime value
| >| | >| type.</param>
| >| | >| public OptionalDateTim e(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(DateTi me
| 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
| >| | >| ArgumentExcepti on("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">T he
| format to
| >| | >| return.</param>
| >| | >| /// <returns>A string containing
| the
| >| | >| correctly formatted date.</returns>
| >| | >| public string GetValue
| (enumDateTimeFo rmat
| >| | >| Format)
| >| | >| {
| >| | >| if(mIsNull)
| >| | >| {
| >| | >| return "";
| >| | >| }
| >| | >| else
| >| | >| {
| >| | >| switch(Format)
| >| | >| {
| >| | >| case
| >| | >| enumDateTimeFor mat.LongDateFor mat:
| >| | >|
| return
| >| | >| mDate.ToLongDat eString();
| >| | >| case
| >| | >| enumDateTimeFor mat.LongTimeFor mat:
| >| | >|
| return
| >| | >| mDate.ToLongTim eString();
| >| | >| case
| >| | >| enumDateTimeFor mat.ShortDateFo rmat:
| >| | >|
| return
| >| | >| mDate.ToShortDa teString();
| >| | >| case
| >| | >| enumDateTimeFor mat.ShortTimeFo rmat:
| >| | >|
| return
| >| | >| mDate.ToShortTi meString();
| >| | >| default:
| >| | >|
| throw new
| >| | >| UnhandledDateFo rmatException(F ormat);
| >| | >| }
| >| | >| }
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Return the value of the
| object as a
| >| | >| ShortDateString .
| >| | >| /// </summary>
| >| | >| /// <returns></returns>
| >| | >| public string GetValue()
| >| | >| {
| >| | >| return GetValue
| >| | >| (enumDateTimeFo rmat.ShortDateF ormat);
| >| | >| }
| >| | >| #endregion
| >| | >|
| >| | >| #region Public Override Methods
| >| | >| /// <summary>
| >| | >| /// Passes a string containing
| the date
| >| | >| in <see
| cref="enumDateT imeFormat.Short DateFormat"/>.
| >| | >| /// </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
| >| | >| OptionalDateTim e as a DateTime type. Raises the
| >| | >| /// <see
| >| | >| cref="OptionalD ateTimeIsNullEx ception"/> if the
| >| | >| OptionalDateTim e 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
| >| | >| OptionalDateTim eIsNullExceptio n();
| >| | >| }
| >| | >| return mDate;
| >| | >| }
| >| | >| }
| >| | >| /// <summary>
| >| | >| /// Gets a boolean value
| indicating
| >| | >| whether the OptionalDateTim e 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
3502
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 add images to my menu buttons they don't show when the form is created. But, if I don't use the XP style the images show on my buttons correctly. Can someone please explain to me what the problem is and how to get around it? Here is how I'm calling...
4
334
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 visual styles enabled, I have no problem. What is wrong and what is the solution? (PS: Using a manifest file makes no trouble. just the function : Application.EnableVisualStyles() ) Thanks for any help.
4
5682
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 logon yet this date should be empty but when binding a property to the DateTimePicker value it always shows value parsed prom property which is 1753-01-01. How to make an "empty" or "not set" date bindable to a value property of DateTimePicker?
3
6391
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 checkbox is focused?
2
2827
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 contains a windows form. How can I enable windows xp styles to this form? (appname.dll.manifest doesn't work)
0
3554
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 (e.g. not a newer .NET control), and is part of the Active-X (.ocx) called MSCOMCT2.OCX (in the \winnt\system32 directory), which I can see that it is there. When I go to add the control to my project (e.g. Projects -> Components) and scroll down...
1
1930
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 click past 59 seconds the minutes do not increment, and similarly for minutes affecting hours. Also, similarly for clicking backwards from 00. I've seen this work in other applications so it must be simple. I could use a value changed event and...
4
3299
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 go about representing this to a user so they are not confused? Thanks,
2
5222
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 supports the Gregorian Calendar, so the earliest date it allows is in 1752 C.E. Is there a way to override the DateTimePicker control's minimum allowed date, or am I forced to resort to the less user-friendly use of three separate text boxes for...
0
8794
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9484
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9342
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9272
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8218
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6056
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4572
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4826
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3286
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.