@@ -60,6 +60,14 @@ public class DateRangePicker : Control
6060 DependencyProperty . Register ( nameof ( IsSyncingDisplayDate ) , typeof ( bool ) , typeof ( DateRangePicker ) ,
6161 new PropertyMetadata ( false , OnIsSyncingDisplayDateChanged ) ) ;
6262
63+ public static readonly DependencyProperty MinDateProperty =
64+ DependencyProperty . Register ( "MinDate" , typeof ( DateTime ? ) , typeof ( DateRangePicker ) ,
65+ new PropertyMetadata ( null , OnMinDateChanged ) ) ;
66+
67+ public static readonly DependencyProperty MaxDateProperty =
68+ DependencyProperty . Register ( "MaxDate" , typeof ( DateTime ? ) , typeof ( DateRangePicker ) ,
69+ new PropertyMetadata ( null , OnMaxDateChanged ) ) ;
70+
6371 private int _clickCount ;
6472
6573 private HwndSource _hwndSource ;
@@ -79,41 +87,53 @@ static DateRangePicker()
7987
8088 public string StartWatermark
8189 {
82- get => ( string ) GetValue ( StartWatermarkProperty ) ;
90+ get => ( string ) GetValue ( StartWatermarkProperty ) ;
8391 set => SetValue ( StartWatermarkProperty , value ) ;
8492 }
8593
8694 public string EndWatermark
8795 {
88- get => ( string ) GetValue ( EndWatermarkProperty ) ;
96+ get => ( string ) GetValue ( EndWatermarkProperty ) ;
8997 set => SetValue ( EndWatermarkProperty , value ) ;
9098 }
9199
92100
93101 public DateTime ? StartDate
94102 {
95- get => ( DateTime ? ) GetValue ( StartDateProperty ) ;
103+ get => ( DateTime ? ) GetValue ( StartDateProperty ) ;
96104 set => SetValue ( StartDateProperty , value ) ;
97105 }
98106
99107 public DateTime ? EndDate
100108 {
101- get => ( DateTime ? ) GetValue ( EndDateProperty ) ;
109+ get => ( DateTime ? ) GetValue ( EndDateProperty ) ;
102110 set => SetValue ( EndDateProperty , value ) ;
103111 }
104112
105113 public string DateFormat
106114 {
107- get => ( string ) GetValue ( DateFormatFormatProperty ) ;
115+ get => ( string ) GetValue ( DateFormatFormatProperty ) ;
108116 set => SetValue ( DateFormatFormatProperty , value ) ;
109117 }
110118
111119 public bool IsSyncingDisplayDate
112120 {
113- get => ( bool ) GetValue ( IsSyncingDisplayDateProperty ) ;
121+ get => ( bool ) GetValue ( IsSyncingDisplayDateProperty ) ;
114122 set => SetValue ( IsSyncingDisplayDateProperty , value ) ;
115123 }
116124
125+ public DateTime ? MinDate
126+ {
127+ get => ( DateTime ? ) GetValue ( MinDateProperty ) ;
128+ set => SetValue ( MinDateProperty , value ) ;
129+ }
130+
131+ public DateTime ? MaxDate
132+ {
133+ get => ( DateTime ? ) GetValue ( MaxDateProperty ) ;
134+ set => SetValue ( MaxDateProperty , value ) ;
135+ }
136+
117137 private static void OnStartDateChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
118138 {
119139 var ctrl = d as DateRangePicker ;
@@ -138,7 +158,7 @@ private static void OnMaxDropDownHeightChanged(DependencyObject d, DependencyPro
138158 {
139159 var ctrl = d as DateRangePicker ;
140160 if ( ctrl != null )
141- ctrl . OnMaxDropDownHeightChanged ( ( double ) e . OldValue , ( double ) e . NewValue ) ;
161+ ctrl . OnMaxDropDownHeightChanged ( ( double ) e . OldValue , ( double ) e . NewValue ) ;
142162 }
143163
144164 protected virtual void OnMaxDropDownHeightChanged ( double oldValue , double newValue )
@@ -149,13 +169,35 @@ private static void OnIsSyncingDisplayDateChanged(DependencyObject d, Dependency
149169 {
150170 var ctrl = d as DateRangePicker ;
151171 if ( ctrl != null )
152- ctrl . OnIsSyncingDisplayDateChanged ( ( bool ) e . OldValue , ( bool ) e . NewValue ) ;
172+ ctrl . OnIsSyncingDisplayDateChanged ( ( bool ) e . OldValue , ( bool ) e . NewValue ) ;
153173 }
154174
155175 protected virtual void OnIsSyncingDisplayDateChanged ( bool oldValue , bool newValue )
156176 {
157177 }
158178
179+ private static void OnMinDateChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
180+ {
181+ var control = ( DateRangePicker ) d ;
182+ if ( control . _startCalendar != null )
183+ OnMinAndMaxChanged ( control ) ;
184+ }
185+
186+ private static void OnMaxDateChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
187+ {
188+ var control = ( DateRangePicker ) d ;
189+ if ( control . _endCalendar != null )
190+ OnMinAndMaxChanged ( control ) ;
191+ }
192+
193+ static void OnMinAndMaxChanged ( DateRangePicker control )
194+ {
195+ control . _startCalendar . BlackoutDates . Add ( new CalendarDateRange ( DateTime . MinValue , control . MinDate . Value . AddDays ( - 1 ) ) ) ;
196+ control . _endCalendar . BlackoutDates . Add ( new CalendarDateRange ( DateTime . MinValue , control . MinDate . Value . AddDays ( - 1 ) ) ) ;
197+ control . _startCalendar . BlackoutDates . Add ( new CalendarDateRange ( control . MaxDate . Value . AddDays ( 1 ) , DateTime . MaxValue ) ) ;
198+ control . _endCalendar . BlackoutDates . Add ( new CalendarDateRange ( control . MaxDate . Value . AddDays ( 1 ) , DateTime . MaxValue ) ) ;
199+ }
200+
159201 public override void OnApplyTemplate ( )
160202 {
161203 base . OnApplyTemplate ( ) ;
@@ -173,7 +215,7 @@ public override void OnApplyTemplate()
173215 }
174216 }
175217
176- _popup = ( Popup ) GetTemplateChild ( PopupTemplateName ) ;
218+ _popup = ( Popup ) GetTemplateChild ( PopupTemplateName ) ;
177219 if ( _popup != null )
178220 {
179221 _popup . Focusable = true ;
@@ -186,7 +228,7 @@ public override void OnApplyTemplate()
186228
187229 AddHandler ( PreviewMouseUpEvent , new MouseButtonEventHandler ( OnPreviewMouseUp ) , true ) ;
188230
189- _startCalendar = ( Calendar ) GetTemplateChild ( StartCalendarTemplateName ) ;
231+ _startCalendar = ( Calendar ) GetTemplateChild ( StartCalendarTemplateName ) ;
190232 if ( _startCalendar != null )
191233 {
192234 _startCalendar . PreviewMouseUp -= OnCalendar_PreviewMouseUp ;
@@ -197,7 +239,7 @@ public override void OnApplyTemplate()
197239 _startCalendar . PreviewMouseUp += OnStartCalendar_PreviewMouseUp ;
198240 }
199241
200- _endCalendar = ( Calendar ) GetTemplateChild ( EndCalendarTemplateName ) ;
242+ _endCalendar = ( Calendar ) GetTemplateChild ( EndCalendarTemplateName ) ;
201243 if ( _endCalendar != null )
202244 {
203245 _endCalendar . PreviewMouseUp -= OnCalendar_PreviewMouseUp ;
@@ -208,8 +250,23 @@ public override void OnApplyTemplate()
208250 _endCalendar . PreviewMouseUp += OnEndCalendar_PreviewMouseUp ;
209251 }
210252
211- var now = DateTime . Now ;
253+ if ( _startCalendar != null )
254+ {
255+ if ( MinDate != null )
256+ _startCalendar . BlackoutDates . Add ( new CalendarDateRange ( DateTime . MinValue , MinDate . Value . AddDays ( - 1 ) ) ) ;
257+ if ( MaxDate != null )
258+ _startCalendar . BlackoutDates . Add ( new CalendarDateRange ( MaxDate . Value . AddDays ( 1 ) , DateTime . MaxValue ) ) ;
259+ }
260+ if ( _endCalendar != null )
261+ {
262+ if ( MinDate != null )
263+ _endCalendar . BlackoutDates . Add ( new CalendarDateRange ( DateTime . MinValue , MinDate . Value . AddDays ( - 1 ) ) ) ;
264+ if ( MaxDate != null )
265+ _endCalendar . BlackoutDates . Add ( new CalendarDateRange ( MaxDate . Value . AddDays ( 1 ) , DateTime . MaxValue ) ) ;
266+ }
267+ var now = MinDate == null ? DateTime . Now : MinDate . Value ;
212268 var firstDayOfNextMonth = new DateTime ( now . Year , now . Month , 1 ) . AddMonths ( 1 ) ;
269+ _startCalendar . DisplayDate = now ;
213270 _startCalendar . DisplayDateEnd = firstDayOfNextMonth . AddDays ( - 1 ) ;
214271 _endCalendar . DisplayDate = firstDayOfNextMonth ;
215272 _endCalendar . DisplayDateStart = firstDayOfNextMonth ;
@@ -219,10 +276,10 @@ public override void OnApplyTemplate()
219276
220277 _startCalendarDayButtons = GetCalendarDayButtons ( _startCalendar ) ;
221278 _endCalendarDayButtons = GetCalendarDayButtons ( _endCalendar ) ;
222- _textBoxStart = ( DatePickerTextBox ) GetTemplateChild ( TextBoxStartTemplateName ) ;
279+ _textBoxStart = ( DatePickerTextBox ) GetTemplateChild ( TextBoxStartTemplateName ) ;
223280 if ( _textBoxStart != null )
224281 _textBoxStart . TextChanged += TextBoxStart_TextChanged ;
225- _textBoxEnd = ( DatePickerTextBox ) GetTemplateChild ( TextBoxEndTemplateName ) ;
282+ _textBoxEnd = ( DatePickerTextBox ) GetTemplateChild ( TextBoxEndTemplateName ) ;
226283 if ( _textBoxEnd != null )
227284 _textBoxEnd . TextChanged += TextBoxEnd_TextChanged ;
228285 Loaded += DateRangePicker_Loaded ;
0 commit comments