0

I'm trying to compare two dates selected from two DatePickers, if the end date is lower than start date the button must be disabled, this is my xaml structure:

<DatePicker x:Name="StartDate" />
<DatePicker x:Name="EndDate" />

<Button>
  <Button.Resources>
    <Style TargetType="Button" BasedOn="{StaticResource ButtonStyle}">
      <Style.Triggers>
        <DataTrigger Value="True">
          <DataTrigger.Binding>
            <MultiBinding>
              <MultiBinding.Converter>
                <Converters:DateComparer />
              </MultiBinding.Converter>
              <Binding ElementName="StartDate" Path="SelectedDate"/>
              <Binding ElementName="EndDate" Path="SelectedDate" />
            </MultiBinding>
          </DataTrigger.Binding>
          <Setter Property="IsEnabled" Value="False" />
        </DataTrigger>
      </Style.Triggers>
    </Style>                             
  </Button.Resources>
</Button>

this is my converter:

public class DateComparer : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length < 2)
            return false;

        DateTime startDate = DateTime.ParseExact(values[0].ToString(),
                "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);

        DateTime endDate = DateTime.ParseExact(values[1].ToString(),
                "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);

        //La data finale è minore della data iniziale
        if (endDate < startDate)
            return true;

        return false;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

on the values object I get Unsect Value, why?

Neuron
  • 5,141
  • 5
  • 38
  • 59
Magheggio
  • 29
  • 5
  • The selected date on a datepicker is datetime?. Just null check and cast to datetime to compare cast to datetime. – Andy Apr 15 '18 at 17:39
  • It's unclear why you have this DataTrigger at all. You could as well directly assign the MultiBinding to the IsEnabled property. – Clemens Apr 15 '18 at 18:53
  • @Clemens you can't compare two date in a multibinding – Magheggio Apr 15 '18 at 19:49
  • What do you mean? You would use the same converter of course, with inverted result or inverted comparison. – Clemens Apr 15 '18 at 19:58
  • @Clemens from your comment I though you were referring to compare two date from xaml only. As I wrote in the question, my converter should check if `EndDate` is lower than `StartDate`, if yes, then the trigger must disable the button. Actually the Nik fix does not working, mine too.. Oh, and I know why I get `Unsect` value, I don't know why I get `Unset` value with my code, so the duplicate is useless for me. – Magheggio Apr 15 '18 at 20:00
  • @Clemens you could write an example, I don't know what is unclear for you. – Magheggio Apr 15 '18 at 20:22
  • It is not clear why you do not directly bind IsEnabled, instead of setting it by a DataTrigger. So why do you think you need the DataTrigger? – Clemens Apr 15 '18 at 20:23
  • @Clemens the `DataTrigger` evaluate a single property, here I have two datepicker which I need to evaluate two dates, for this I used a MultiBinding, I don't know if you know another way to handle this – Magheggio Apr 15 '18 at 20:26
  • Put the following into your Style instead of the DataTrigger: `...`. – Clemens Apr 15 '18 at 20:37

1 Answers1

0

Judging from your xaml, there is nothing to initialize SelectedDate when the window is first launched, thus it is null. I was able to make it work with your xaml as is, but I had to make some modifications to the converter.

  1. You don't need to call ToString() on your values and then parse them. They are already DateTime
  2. Use the is operator. That both does the null check and discards the unset values during initialization.

Try this as you Convert method:

public object Convert(object[] values, Type targetType, 
                      object parameter, CultureInfo culture)
{
    bool ret = false;
    if (values.Length > 1 && values[0] is DateTime && values[1] is DateTime)
    {
        DateTime startDate = (DateTime)values[0];
        DateTime endDate = (DateTime)values[1];
        ret = endDate < startDate;
    }
    return ret;
}
Nik
  • 1,780
  • 1
  • 14
  • 23
  • when I change the date the converter does not work, but maybe there is another way to disable the button if endDate is lower than startdate directly in xaml? – Magheggio Apr 15 '18 at 19:52
  • just check for the values if they are equal to DependencyProperty.UnsetValue and return false, this will remove initial stage issues. – WPFUser Apr 16 '18 at 06:00