Friends,
I am curious if anyone knows a way to pop a validation messagebox based on what is already taking place in a date bound textbox in Visual Studio 2005. What I mean is this......
Yes, I can write a routine to run through the characters and check if it is a valid date but the textbox (and/or bound dataset ) seems to be doing its own validation. If I do not type in a valid date using a /, ., or -, the form simply will not let me advance to the next record using the navigator, which tells me that the textbox or dataset is doing it's own validation WITHOUT me having to write a whole new method to do it. I even checked an invalid leapyear entry and it wouldn't take that either so there is some serious validation going on already. Question is, where do I call it from
Appreciate any info on this...
J.H.

Date Validation on a Databound Textbox
zacksz
Ok, it's working and here is the class in its entirety...
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace Extreme
{
public class DateTextBox : System.Windows.Forms.TextBox
{
private DateTime _myValue = null;
[Bindable(true)]
[Category("Appearance")]
[Description("Nullable DateTime value.")]
public DateTime Value
{
get { return _myValue; }
set
{
_myValue = value;
if (!value.HasValue)
Text = String.Empty;
else
Text = Convert.ToString(value);
}
}
}
}
Another question for you....How/where do you set the date format for the control Right now, it is displaying long date including the time stamp, which I would like to change to short date format.
Thanks so much for your info...I think alot of people will benefit from this one.
J.H.
Navajo
DateTime is a value type so it can't store null. In C# 2.0 you can define a property as a nullable DateTime with "DateTime ".
See if this would help: Create a new control which inherits from TextBox and add a new property Value to it, and use Value property instead of Text property.
public class DateTextBox : System.Windows.Forms.TextBox
{
private DateTime _myValue = null;
public DateTime Value
{
get { return _myValue; }
set
{
_myValue = value;
if (!value.HasValue)
Text = string.Empty;
else
Text = (DateTime)value;
}
}
}
Sh Dr Cn
Hey J.H.
When you bind a nullable date textbox your business object's property, its data type should be "DateTime " and not "DateTime". You can use BindableAttribute from System.ComponentModel so that you can bind to Value property in the Visual Studio designer. Here's attribute application to the control:
Include following statement at the top of the class file:
using System.ComponentModel;
And then apply following attributes. You need only Bindable attribute for databinding. I always apply Category and Description attributes which helps when you use the control in the designer.
//Promote the use of Value property.
[Bindable(true)]
[Category("Appearance")]
[Description("Nullable DateTime value. In databinding this property must bind with Nullable DateTime field. Otherwise focus will not leave the control when user leaves text empty and datasource expects a non-null DateTime value.")]
public DateTime Value
{
…
}
When you databind to your business object ensure that property is nullable just like Value property of the custom textbox.
Michael K Campbell
You can add a Format property to the class, and use it to update the Text property. Here's how your code could look like:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace Extreme
{
public class DateTextBox : System.Windows.Forms.TextBox
{
private DateTime _myValue = null;
private string _format = "MM/dd/yyyy";
[Bindable(true)]
[Category("Appearance")]
[Description("Nullable DateTime value.")]
public DateTime Value
{
get { return _myValue; }
set
{
_myValue = value;
UpdateText();
}
}
[Bindable(true)]
[Category("Appearance")]
[Description("Date Time format to be displayed in DateTextBox.")]
[DefaultValue("MM/dd/yyyy")]
public string Format
{
get { return _format; }
set { _format = value; }
}
private void UpdateText()
{
if (!_myValue.HasValue)
Text = string.Empty;
else
Text = ((DateTime)_myValue).ToString(Format);
}
}
}
And thorugh Format property you can define how Date should be formatted in your DateTextBox.
Chad_06
LOVE IT! This means I can just about do all my data validation with one event handler based on the data binding types. I did find one issue though with my date textbox. I am allowing nulls in my datasource. If I add a value to the textbox for a record that has a null date field and then delete the entry, my exception is pesisting stating that I need to input a valid date. I am guessing that once I enter a date in the textbox and then delete it, I basically have converted the textbox value to an emtpy string which is not being accepted as a date format. Any thoughts here
Thanks so much for the info!
J.H.
cevans
I came up with a slighly simpler solution...just add the old..
String.Format("{0:d}", value);
to the text assignment line.
Now, I came across the obvious problem with this control using databinding. Changing the text value is not updating the dataset..Obvious because the Text property value is not being written back to the Value property of the datetextbox and this is what is bound to the dataset. I think this should be easy enough to fix by writing an event handler to compare Text to Value but which one should we use
I am thinking Leave or Validating would be the obvious choices and then just set Value = Text. I guess this would also be a great place to do the validation. Thoughts here
J.H.
stormen81
Well, I have played around with some validation ideas but the problem I am having is determining which control is causing the event. This might be justification for going back and writing code against control-based events instead. Unless you have some suggestions here, I might just do that. I'll play around with the null date value above and let you know what I come up with.
J.H.
cyphorous
Here's the event handler I came up with:
First, I declared a class level variable as a DateTextBox called mySender. This way I can determine which DateTextBox is calling the event handler.
private
void dateTextBox1_Validating(object sender, CancelEventArgs e){
mySender = (DateTextBox)sender;
if (this.mySender.Text != "")
{
try
{
if (DateTime.Parse(this.mySender.Text) != this.mySender.Value)
this.mySender.Value = DateTime.Parse(mySender.Text);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Invalid Date Entered", MessageBoxButtons.OK, MessageBoxIcon.Error);
this.mySender.Focus();
}
}
else
{
mySender.Value = null;
}
} J.H.
Regis Brid
OK, I have been playing around with this solution and I am finding that I am unable to bind the datasource to the Value property. Additonally, I was receiving an error saying "unable to implicitely convert datetime to string"...I think I solved this by doing a Convert.ToString() on it instead, but because I am unable to bind the nullable Value property, I am kinda sunk.
Here's a question: As mentioned, in my form, when I clear a textbox that contains a valid date in it, the Navigator will not let me advance to another record or close the screen. I am assuming that what is happening is the bound field is trying to assign an empty string to the DateTime field in the dataset. With this in mind, I am left unsure as to how the solution above would be able to help me by assigning string.empty to the text property manually. Is my assumption incorrect and really what is happening is the textbox binding is trying to assign a NULL to the dataset The simple question is can the DateTime value type accept an empty string in the dataset
LuisSpain
When you use data binding it won't let you get out of the field if its value can't be converted to the data type of the binding field. You can consider using BindingComplete event for a better control. Here is a sample on MSDN:
http://msdn2.microsoft.com/en-us/library/system.windows.forms.binding.bindingcomplete(VS.80).aspx