@@ -54,6 +54,7 @@ public class Calendar : Calendar<CalendarDay, Event>
54
54
private DateTime ? _rangeSelectionStart ;
55
55
private DateTime ? _rangeSelectionEnd ;
56
56
private SelectionType _selectionType = SelectionType . None ;
57
+ private SelectionDirection _selectionDirection = SelectionDirection . Any ;
57
58
private ObservableRangeCollection < TEvent > _events = new ObservableRangeCollection < TEvent > ( ) ;
58
59
#endregion
59
60
@@ -447,6 +448,25 @@ public SelectionType SelectionType
447
448
}
448
449
}
449
450
}
451
+ /// <summary>
452
+ /// The direction a selected date has to be relative to the earliest or latest selected date in order to be applied to the selection.
453
+ /// </summary>
454
+ public SelectionDirection SelectionDirection
455
+ {
456
+ get
457
+ {
458
+ return _selectionDirection ;
459
+ }
460
+ set
461
+ {
462
+ if ( _selectionDirection != value )
463
+ {
464
+ _selectionDirection = value ;
465
+
466
+ OnPropertyChanged ( nameof ( SelectionDirection ) ) ;
467
+ }
468
+ }
469
+ }
450
470
public ObservableRangeCollection < TEvent > Events
451
471
{
452
472
get
@@ -537,6 +557,9 @@ protected virtual void OnDaysUpdating()
537
557
/// <param name="dateTime">The <see cref="DateTime"/> to select/unselect.</param>
538
558
public virtual void ChangeDateSelection ( DateTime dateTime )
539
559
{
560
+ DateTime ? startSelectedDate = SelectedDates . Any ( ) ? SelectedDates . Min ( ) : ( DateTime ? ) null ;
561
+ DateTime ? endSelectedDate = SelectedDates . Skip ( 1 ) . Any ( ) ? SelectedDates . Max ( ) : ( DateTime ? ) null ;
562
+
540
563
switch ( SelectionType )
541
564
{
542
565
case SelectionType . None :
@@ -546,11 +569,41 @@ public virtual void ChangeDateSelection(DateTime dateTime)
546
569
switch ( SelectionAction )
547
570
{
548
571
case SelectionAction . Add :
549
- if ( ! SelectedDates . Any ( x => x . Date == dateTime . Date ) )
550
572
{
551
- SelectedDates . Add ( dateTime . Date ) ;
573
+ bool isCorrectDirection ;
574
+
575
+ switch ( SelectionDirection )
576
+ {
577
+ case SelectionDirection . Any :
578
+ isCorrectDirection = true ;
579
+ break ;
580
+
581
+ case SelectionDirection . StartToEnd :
582
+ isCorrectDirection = startSelectedDate == null || dateTime . Date >= startSelectedDate . Value . Date ;
583
+ break ;
584
+
585
+ case SelectionDirection . EndToStart :
586
+ isCorrectDirection = endSelectedDate == null || dateTime . Date <= endSelectedDate . Value . Date ;
587
+ break ;
588
+
589
+ case SelectionDirection . Confined :
590
+ isCorrectDirection = startSelectedDate == null || endSelectedDate == null || ( dateTime . Date >= startSelectedDate . Value . Date && dateTime . Date <= endSelectedDate . Value . Date ) ;
591
+ break ;
592
+
593
+ case SelectionDirection . ConfinedReverse :
594
+ isCorrectDirection = startSelectedDate == null || endSelectedDate == null || dateTime . Date <= startSelectedDate . Value . Date || dateTime . Date >= endSelectedDate . Value . Date ;
595
+ break ;
596
+
597
+ default :
598
+ throw new NotImplementedException ( ) ;
599
+ }
600
+
601
+ if ( isCorrectDirection && ! SelectedDates . Any ( x => x . Date == dateTime . Date ) )
602
+ {
603
+ SelectedDates . Add ( dateTime . Date ) ;
604
+ }
605
+ break ;
552
606
}
553
- break ;
554
607
555
608
case SelectionAction . Remove :
556
609
if ( SelectedDates . Any ( x => x . Date == dateTime . Date ) )
@@ -566,12 +619,43 @@ public virtual void ChangeDateSelection(DateTime dateTime)
566
619
}
567
620
else
568
621
{
569
- SelectedDates . Add ( dateTime . Date ) ;
622
+ bool isCorrectDirection ;
623
+
624
+ switch ( SelectionDirection )
625
+ {
626
+ case SelectionDirection . Any :
627
+ isCorrectDirection = true ;
628
+ break ;
629
+
630
+ case SelectionDirection . StartToEnd :
631
+ isCorrectDirection = startSelectedDate == null || dateTime . Date >= startSelectedDate . Value . Date ;
632
+ break ;
633
+
634
+ case SelectionDirection . EndToStart :
635
+ isCorrectDirection = endSelectedDate == null || dateTime . Date <= endSelectedDate . Value . Date ;
636
+ break ;
637
+
638
+ case SelectionDirection . Confined :
639
+ isCorrectDirection = startSelectedDate == null || endSelectedDate == null || ( dateTime . Date >= startSelectedDate . Value . Date && dateTime . Date <= endSelectedDate . Value . Date ) ;
640
+ break ;
641
+
642
+ case SelectionDirection . ConfinedReverse :
643
+ isCorrectDirection = startSelectedDate == null || endSelectedDate == null || dateTime . Date <= startSelectedDate . Value . Date || dateTime . Date >= endSelectedDate . Value . Date ;
644
+ break ;
645
+
646
+ default :
647
+ throw new NotImplementedException ( ) ;
648
+ }
649
+
650
+ if ( isCorrectDirection )
651
+ {
652
+ SelectedDates . Add ( dateTime . Date ) ;
653
+ }
570
654
}
571
655
break ;
572
656
573
657
case SelectionAction . Replace :
574
- if ( SelectedDates . Count != 1 || ( SelectedDates . Count == 1 && SelectedDates . First ( ) . Date != dateTime . Date ) )
658
+ if ( SelectedDates . Count != 1 || ( SelectedDates . Count == 1 && SelectedDates . First ( ) != dateTime . Date ) )
575
659
{
576
660
SelectedDates . Replace ( dateTime . Date ) ;
577
661
}
@@ -593,7 +677,38 @@ public virtual void ChangeDateSelection(DateTime dateTime)
593
677
}
594
678
else if ( dateTime != RangeSelectionStart )
595
679
{
596
- RangeSelectionEnd = dateTime ;
680
+ bool isCorrectDirection ;
681
+
682
+ switch ( SelectionDirection )
683
+ {
684
+ case SelectionDirection . Any :
685
+ isCorrectDirection = true ;
686
+ break ;
687
+
688
+ case SelectionDirection . StartToEnd :
689
+ isCorrectDirection = startSelectedDate == null || dateTime . Date >= startSelectedDate . Value . Date ;
690
+ break ;
691
+
692
+ case SelectionDirection . EndToStart :
693
+ isCorrectDirection = endSelectedDate == null || dateTime . Date <= endSelectedDate . Value . Date ;
694
+ break ;
695
+
696
+ case SelectionDirection . Confined :
697
+ isCorrectDirection = startSelectedDate == null || endSelectedDate == null || ( dateTime . Date >= startSelectedDate . Value . Date && dateTime . Date <= endSelectedDate . Value . Date ) ;
698
+ break ;
699
+
700
+ case SelectionDirection . ConfinedReverse :
701
+ isCorrectDirection = startSelectedDate == null || endSelectedDate == null || dateTime . Date <= startSelectedDate . Value . Date || dateTime . Date >= endSelectedDate . Value . Date ;
702
+ break ;
703
+
704
+ default :
705
+ throw new NotImplementedException ( ) ;
706
+ }
707
+
708
+ if ( isCorrectDirection )
709
+ {
710
+ RangeSelectionEnd = dateTime ;
711
+ }
597
712
}
598
713
break ;
599
714
0 commit comments