views:

280

answers:

4

Hi,

I have a simple form, with two DateTimePicker-controls: One for date, and one for time. The thing is these two controls are supposed to represent a single point in time. Hence I would like to "Bind" them to a single DateTime property on my form (for simplicity). I did the following:

// Start is a DateTime property on the form
_StartDate.DataBindings.Add("Value", this, "Start"); 
_StartTime.DataBindings.Add("Value", this, "Start");

But hooking into "ValueChanged" event, yields mixed results... Sometimes I get exactly what I want, sometimes the updates of the property are "sluggish". I figured this way of splitting into two DateTimePicker's was fairly common. So how to do it?

Update: There is possibly multiple questions in there:

  1. How do I bind a DateTimePicker (Format: Date) to a DateTime Property on a form?
  2. Then, how do I bind yet another DateTimePicker (Format: Time) to the same property?
  3. I'm using Visual Studio Express 2008 (.NET 3.5), and I seemingly get ValueChanged events from the DateTimePickers before the value is changed?
+1  A: 

Unfortunately, I think you may be finding yourself writing a custom control that includes both, which you can data bind to. That's how we solved the same problem.

Neil Whitaker
Really? I thought this was so common, that it was possible out-of-the-box. Go figure...
S.C. Madsen
I agree. It really ought to be available out-of-the-box.
Neil Whitaker
+1  A: 

I find myself having this problem on occasion and I use a somewhat ugly technique. Instead of binding directly to the property I create two additional properties on the model.

//The data I want to bind to
public DateTime Something { get; set; }
//Two new properties
public DateTime SomethingDate { /*...*/ }
public DateTime SomethingTime { /*...*/ }

The get sections of each should merely return Something. The set sections is where you implement a tiny bit of logic to ensure Something is always reflected accurately.

public DateTime SomethingDate
{
    get
    {
        return this.Something;
    }
    set
    {
        this.Something = value.Date.Add(this.Something.TimeOfDay);
    }
}
public DateTime SomethingTime
{
    get
    {
        return this.Something;
    }
    set
    {
        this.Something = this.Something.Date.Add(value.TimeOfDay);
    }
}

Now your Something property will always properly reflect the corresponding date and times of the two controls while only updating the value with the piece of information from each that we care about.

Jake Wharton
I'll try this to see if that solves my current problem. Thanks!
S.C. Madsen
Could you explain exactly how you do the binding then? I tried writing the "Something" to the Console on the ValueChangedEvent of the DataPicker bound to "SomethingDate". But when I pick a new date, the Console keeps writing the same date over and over.
S.C. Madsen
A: 

If you're open to using a jQuery-based picker, the Any+Time™ DatePicker/TimePicker AJAX Calendar Widget allows you to pick both the date and time using a single control.

Andrew M. Andrews III
A: 

You can't directly bind DateTime struct member with a Binding Class, for do it you have to wrap a DateTime struct and Implement the PropertyChanged event of the INotifyPropertyChanged interface like this one:

public class DateTimeWrapper : INotifyPropertyChanged
{
    private DateTime _dateTime;
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged()
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs("Value"));
    }

    public DateTime Value
    {
        get { return _dateTime; }
        set
        {
            _dateTime = value;
            OnPropertyChanged();
        }
    }
}

and after that you can use a Bindig object like this:

var binding = new Binding("Value", _time, "Value", true);
binding.ControlUpdateMode = ControlUpdateMode.OnPropertyChanged;
dateTimePicker1.DataBindings.Add(binding);
Max