1

I am using the WPFToolkit for a MVVM WPF application, and trying to set up Blackout dates for the End Date to be based on the Start Date.

Example 1:

 <toolkit:DatePicker SelectedDate="{Binding StartDate}"></toolkit:DatePicker>

Example 2:

<toolkit:DatePicker SelectedDate="{Binding EndDate}">
     <toolkit:DatePicker.BlackoutDates>
          <toolkit:CalendarDateRange Start="1/1/2000" End="{Binding StartDate}" />
     </toolkit:DatePicker.BlackoutDates>
</toolkit:DatePicker>

I get error stating that "End" cannot have a Binding

How do I do this?

jmogera
  • 1,689
  • 3
  • 30
  • 65

2 Answers2

1

I think you'll need to build your own DatePicker if you want this behavior because it looks like the toolkit one's End property is not a DependencyProperty, so the End property cannot point to a Binding

I've had a similar situation in the past where I didn't want the StartDate to come after the EndDate and I just ended up using validation errors, which puts a red border around the date field if it's invalid.

Community
  • 1
  • 1
Rachel
  • 130,264
  • 66
  • 304
  • 490
1

I had this same task where two date fields had to coordinate with each other. I also had other business logic that had to be implemented along with the date validation (such as when and when not to enforce the validation).

To get this functionality I used the WPF DataValidation Rules.

 public class ValidateDate : ValidationRule
    {    
        public DateTime EndDate { get; set; }

        /// <summary>
        /// Validates date is valid
        /// </summary>
        /// <param name="value"></param>
        /// <param name="cultureInfo"></param>
        /// <returns></returns>
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            // Return if null
            if (value == null)
            {
                return new ValidationResult(true, null);
            }

            DateTime t;
            if (!DateTime.TryParse(value.ToString(), out t))
                return new ValidationResult(false, null);

            if(t == null)
            {
                return new ValidationResult(true, null);
            }

            if (t.Date < EndDate )
            {
                string message = "Invalid Date";  
                return new ValidationResult(false, message);
            }
            else
            {
                return new ValidationResult(true, null);
            }
        }

Here is the bindings being applied in code behind.

System.Windows.Data.Binding b1 = BindingOperations.GetBinding(dpMyDate,
                                                                         DatePicker.SelectedDateProperty);

b1.ValidationRules.Clear(); // Clear as I reuse them
ValidateDate vd = new ValidateDate();
vd.EndDate = datePickerEndDate.SelectedDate;
b1.ValidationRules.Add(vd);

By using this method you can prevent the users from selecting an invalid date and setup a style on your date pickers when they are invalid like below.

<Style TargetType="{x:Type DatePicker}">            
            <Setter Property="Width" Value="110"/>
            <Setter Property="Margin" Value="5"  />
            <Setter Property="HorizontalAlignment" Value="Left"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="Text" Value="No Date" />
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="BorderBrush" Value="Red"/>
                    <Setter Property="BorderThickness" Value="1" />
                    <Setter Property="Foreground" Value="Red" />
                    <Setter 
                        Property="ToolTip" 
                        Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.Errors)[0].ErrorContent}" />
                </Trigger>
            </Style.Triggers>
        </Style>
tsells
  • 2,751
  • 1
  • 18
  • 20