diff --git a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml
index d7810a5..82951c5 100644
--- a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml
+++ b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml
@@ -9,6 +9,6 @@
-
+
diff --git a/src/Ursa.Themes.Semi/Controls/DatePicker.axaml b/src/Ursa.Themes.Semi/Controls/DatePicker.axaml
index 260bb58..6325342 100644
--- a/src/Ursa.Themes.Semi/Controls/DatePicker.axaml
+++ b/src/Ursa.Themes.Semi/Controls/DatePicker.axaml
@@ -40,6 +40,9 @@
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
+ Watermark="{TemplateBinding Watermark}"
+ InnerLeftContent="{TemplateBinding InnerLeftContent}"
+ InnerRightContent="{TemplateBinding InnerRightContent}"
CornerRadius="{TemplateBinding CornerRadius}"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource LooklessTextBox}"
diff --git a/src/Ursa.Themes.Semi/Controls/DateRangePicker.axaml b/src/Ursa.Themes.Semi/Controls/DateRangePicker.axaml
new file mode 100644
index 0000000..0cc449b
--- /dev/null
+++ b/src/Ursa.Themes.Semi/Controls/DateRangePicker.axaml
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml
index 232557f..1fd38a9 100644
--- a/src/Ursa.Themes.Semi/Controls/_index.axaml
+++ b/src/Ursa.Themes.Semi/Controls/_index.axaml
@@ -9,6 +9,7 @@
+
diff --git a/src/Ursa/Controls/DateTimePicker/CalendarView.cs b/src/Ursa/Controls/DateTimePicker/CalendarView.cs
index b3c0063..547dbec 100644
--- a/src/Ursa/Controls/DateTimePicker/CalendarView.cs
+++ b/src/Ursa/Controls/DateTimePicker/CalendarView.cs
@@ -140,7 +140,6 @@ public class CalendarView : TemplatedControl
InitializeGridButtons();
UpdateDayButtons();
UpdateYearButtons();
- UpdateHeaderButtons();
}
private void OnFastNext(object sender, RoutedEventArgs e)
@@ -150,8 +149,6 @@ public class CalendarView : TemplatedControl
ContextCalendar.Year += 1;
UpdateDayButtons();
}
-
- UpdateHeaderButtons();
}
private void OnNext(object sender, RoutedEventArgs e)
@@ -184,8 +181,6 @@ public class CalendarView : TemplatedControl
ContextCalendar.EndYear += 100;
UpdateYearButtons();
}
-
- UpdateHeaderButtons();
}
private void OnPrevious(object sender, RoutedEventArgs e)
@@ -218,8 +213,6 @@ public class CalendarView : TemplatedControl
ContextCalendar.EndYear -= 100;
UpdateYearButtons();
}
-
- UpdateHeaderButtons();
}
private void OnFastPrevious(object sender, RoutedEventArgs e)
@@ -229,8 +222,6 @@ public class CalendarView : TemplatedControl
ContextCalendar.Year -= 1;
UpdateDayButtons();
}
-
- UpdateHeaderButtons();
}
///
@@ -248,7 +239,6 @@ public class CalendarView : TemplatedControl
var range = DateTimeHelper.GetDecadeViewRangeByYear(ContextCalendar.Year!.Value);
ContextCalendar.StartYear = range.start;
ContextCalendar.EndYear = range.end;
- UpdateHeaderButtons();
UpdateYearButtons();
return;
}
@@ -259,7 +249,6 @@ public class CalendarView : TemplatedControl
var range = DateTimeHelper.GetCenturyViewRangeByYear(ContextCalendar.StartYear!.Value);
ContextCalendar.StartYear = range.start;
ContextCalendar.EndYear = range.end;
- UpdateHeaderButtons();
UpdateYearButtons();
return;
}
@@ -314,7 +303,7 @@ public class CalendarView : TemplatedControl
}
}
- private void UpdateDayButtons()
+ internal void UpdateDayButtons()
{
if (_monthGrid is null || Mode != CalendarViewMode.Month) return;
var children = _monthGrid.Children;
@@ -335,6 +324,7 @@ public class CalendarView : TemplatedControl
FadeOutDayButtons();
MarkDates(_start, _end, _previewStart, _previewEnd);
+ UpdateHeaderButtons();
}
private void UpdateYearButtons()
@@ -374,6 +364,7 @@ public class CalendarView : TemplatedControl
child?.SetContext(CalendarViewMode.Year, new CalendarContext { Month = i });
}
}
+ UpdateHeaderButtons();
}
private void FadeOutDayButtons()
@@ -412,7 +403,7 @@ public class CalendarView : TemplatedControl
private void OnCellDatePreviewed(object sender, CalendarDayButtonEventArgs e)
{
- OnDatePreviewed?.Invoke(sender, e);
+ OnDatePreviewed?.Invoke(this, e);
}
private void OnCellDateSelected(object sender, CalendarDayButtonEventArgs e)
@@ -423,10 +414,9 @@ public class CalendarView : TemplatedControl
ContextCalendar.Year = e.Date.Year;
ContextCalendar.Day = 1;
UpdateDayButtons();
- UpdateHeaderButtons();
}
- OnDateSelected?.Invoke(sender, e);
+ OnDateSelected?.Invoke(this, e);
}
///
@@ -437,7 +427,6 @@ public class CalendarView : TemplatedControl
private void OnHeaderMonthButtonClick(object sender, RoutedEventArgs e)
{
SetCurrentValue(ModeProperty, CalendarViewMode.Year);
- UpdateHeaderButtons();
UpdateYearButtons();
}
@@ -453,7 +442,6 @@ public class CalendarView : TemplatedControl
var range = DateTimeHelper.GetDecadeViewRangeByYear(ContextCalendar.Year!.Value);
ContextCalendar.StartYear = range.start;
ContextCalendar.EndYear = range.end;
- UpdateHeaderButtons();
UpdateYearButtons();
}
diff --git a/src/Ursa/Controls/DateTimePicker/DatePicker.cs b/src/Ursa/Controls/DateTimePicker/DatePicker.cs
index 8463aa5..e1c802f 100644
--- a/src/Ursa/Controls/DateTimePicker/DatePicker.cs
+++ b/src/Ursa/Controls/DateTimePicker/DatePicker.cs
@@ -34,6 +34,15 @@ public class DatePicker: DatePickerBase, IClearControl
set => SetValue(SelectedDateProperty, value);
}
+ public static readonly StyledProperty WatermarkProperty = AvaloniaProperty.Register(
+ nameof(Watermark));
+
+ public string? Watermark
+ {
+ get => GetValue(WatermarkProperty);
+ set => SetValue(WatermarkProperty, value);
+ }
+
static DatePicker()
{
SelectedDateProperty.Changed.AddClassHandler((picker, args) =>
@@ -86,6 +95,7 @@ public class DatePicker: DatePickerBase, IClearControl
private void OnDateSelected(object sender, CalendarDayButtonEventArgs e)
{
SetCurrentValue(SelectedDateProperty, e.Date);
+ SetCurrentValue(IsDropdownOpenProperty, false);
}
private void OnButtonClick(object sender, RoutedEventArgs e)
@@ -96,6 +106,12 @@ public class DatePicker: DatePickerBase, IClearControl
private void OnTextBoxPointerPressed(object sender, PointerPressedEventArgs e)
{
+ if (_calendar is not null)
+ {
+ var date = SelectedDate ?? DateTime.Today;
+ _calendar.ContextCalendar = new CalendarContext(date.Year, date.Month, 1);
+ _calendar.UpdateDayButtons();
+ }
SetCurrentValue(IsDropdownOpenProperty, true);
}
@@ -120,6 +136,12 @@ public class DatePicker: DatePickerBase, IClearControl
out var date))
{
SetCurrentValue(SelectedDateProperty, date);
+ if (_calendar is not null)
+ {
+ var d = SelectedDate ?? DateTime.Today;
+ _calendar.ContextCalendar = new CalendarContext(date.Year, date.Month, 1);
+ _calendar.UpdateDayButtons();
+ }
_calendar?.MarkDates(startDate: date, endDate: date);
}
}
@@ -127,7 +149,13 @@ public class DatePicker: DatePickerBase, IClearControl
private void OnTextBoxGetFocus(object sender, GotFocusEventArgs e)
{
- SetCurrentValue(IsDropdownOpenProperty, true);
+ if (_calendar is not null)
+ {
+ var date = SelectedDate ?? DateTime.Today;
+ _calendar.ContextCalendar = new CalendarContext(date.Year, date.Month, 1);
+ _calendar.UpdateDayButtons();
+ }
+ SetCurrentValue(IsDropdownOpenProperty, true);
}
protected override void OnKeyDown(KeyEventArgs e)
diff --git a/src/Ursa/Controls/DateTimePicker/DateRangePicker.cs b/src/Ursa/Controls/DateTimePicker/DateRangePicker.cs
index 0564cdf..1ad45d9 100644
--- a/src/Ursa/Controls/DateTimePicker/DateRangePicker.cs
+++ b/src/Ursa/Controls/DateTimePicker/DateRangePicker.cs
@@ -1,8 +1,275 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
+using Avalonia.Input;
+using Avalonia.Interactivity;
+using Irihi.Avalonia.Shared.Helpers;
namespace Ursa.Controls;
-public class DateRangePicker : TemplatedControl
+[TemplatePart(PART_Button, typeof(Button))]
+[TemplatePart(PART_Popup, typeof(Popup))]
+[TemplatePart(PART_StartCalendar, typeof(CalendarView))]
+[TemplatePart(PART_EndCalendar, typeof(CalendarView))]
+[TemplatePart(PART_StartTextBox, typeof(TextBox))]
+[TemplatePart(PART_EndTextBox, typeof(TextBox))]
+public class DateRangePicker : DatePickerBase
{
+ public const string PART_Button = "PART_Button";
+ public const string PART_Popup = "PART_Popup";
+ public const string PART_StartCalendar = "PART_StartCalendar";
+ public const string PART_EndCalendar = "PART_EndCalendar";
+ public const string PART_StartTextBox = "PART_StartTextBox";
+ public const string PART_EndTextBox = "PART_EndTextBox";
+
+ public static readonly StyledProperty SelectedStartDateProperty =
+ AvaloniaProperty.Register(
+ nameof(SelectedStartDate));
+
+ public static readonly StyledProperty SelectedEndDateProperty =
+ AvaloniaProperty.Register(
+ nameof(SelectedEndDate));
+
+ private Button? _button;
+ private CalendarView? _endCalendar;
+ private TextBox? _endTextBox;
+ private Popup? _popup;
+ private CalendarView? _startCalendar;
+ private TextBox? _startTextBox;
+
+ static DateRangePicker()
+ {
+ SelectedStartDateProperty.Changed.AddClassHandler((picker, args) =>
+ picker.OnSelectionChanged(args));
+ SelectedEndDateProperty.Changed.AddClassHandler((picker, args) =>
+ picker.OnSelectionChanged(args));
+ }
+
+ public DateTime? SelectedStartDate
+ {
+ get => GetValue(SelectedStartDateProperty);
+ set => SetValue(SelectedStartDateProperty, value);
+ }
+
+ public DateTime? SelectedEndDate
+ {
+ get => GetValue(SelectedEndDateProperty);
+ set => SetValue(SelectedEndDateProperty, value);
+ }
+
+
+ private void OnSelectionChanged(AvaloniaPropertyChangedEventArgs args)
+ {
+ if (args.Property == SelectedStartDateProperty)
+ {
+ if (args.NewValue.Value is null)
+ {
+ _startCalendar?.ClearSelection();
+ _startTextBox?.Clear();
+ }
+ else
+ {
+ _startCalendar?.MarkDates(args.NewValue.Value, args.NewValue.Value);
+ _startTextBox?.SetValue(TextBox.TextProperty,
+ args.NewValue.Value.Value.ToString(DisplayFormat ?? "yyyy-MM-dd"));
+ }
+ }
+ else if (args.Property == SelectedEndDateProperty)
+ {
+ if (args.NewValue.Value is null)
+ {
+ _endCalendar?.ClearSelection();
+ _endTextBox?.Clear();
+ }
+ else
+ {
+ _endCalendar?.MarkDates(args.NewValue.Value, args.NewValue.Value);
+ _endTextBox?.SetValue(TextBox.TextProperty,
+ args.NewValue.Value.Value.ToString(DisplayFormat ?? "yyyy-MM-dd"));
+ }
+ }
+ }
+
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+ GotFocusEvent.RemoveHandler(OnTextBoxGetFocus, _startTextBox);
+ TextBox.TextChangedEvent.RemoveHandler(OnTextChanged, _startTextBox, _endTextBox);
+ PointerPressedEvent.RemoveHandler(OnTextBoxPointerPressed, _startTextBox, _endTextBox);
+ Button.ClickEvent.RemoveHandler(OnButtonClick, _button);
+ if (_startCalendar != null)
+ {
+ _startCalendar.OnDateSelected -= OnDateSelected;
+ _startCalendar.OnDatePreviewed -= OnDatePreviewed;
+ }
+ if (_endCalendar != null)
+ {
+ _endCalendar.OnDateSelected -= OnDateSelected;
+ _endCalendar.OnDatePreviewed -= OnDatePreviewed;
+ }
+ _button = e.NameScope.Find