Skip to content

Commit

Permalink
Merge pull request #4343 from FoggyFinder/timePickerFix4342
Browse files Browse the repository at this point in the history
[ TimePicker ] Reset column indexes in a Grid to avoid exception
  • Loading branch information
danwalmsley authored Jul 21, 2020
2 parents 7f2c9be + 18b8564 commit 70a0f00
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 53 deletions.
51 changes: 18 additions & 33 deletions src/Avalonia.Controls/DateTimePickers/TimePicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class TimePicker : TemplatedControl
/// Defines the <see cref="MinuteIncrement"/> property
/// </summary>
public static readonly DirectProperty<TimePicker, int> MinuteIncrementProperty =
AvaloniaProperty.RegisterDirect<TimePicker, int>(nameof(MinuteIncrement),
AvaloniaProperty.RegisterDirect<TimePicker, int>(nameof(MinuteIncrement),
x => x.MinuteIncrement, (x, v) => x.MinuteIncrement = v);

/// <summary>
Expand All @@ -34,25 +34,25 @@ public class TimePicker : TemplatedControl
/// Defines the <see cref="ClockIdentifier"/> property
/// </summary>
public static readonly DirectProperty<TimePicker, string> ClockIdentifierProperty =
AvaloniaProperty.RegisterDirect<TimePicker, string>(nameof(ClockIdentifier),
AvaloniaProperty.RegisterDirect<TimePicker, string>(nameof(ClockIdentifier),
x => x.ClockIdentifier, (x, v) => x.ClockIdentifier = v);

/// <summary>
/// Defines the <see cref="SelectedTime"/> property
/// </summary>
public static readonly DirectProperty<TimePicker, TimeSpan?> SelectedTimeProperty =
AvaloniaProperty.RegisterDirect<TimePicker, TimeSpan?>(nameof(SelectedTime),
AvaloniaProperty.RegisterDirect<TimePicker, TimeSpan?>(nameof(SelectedTime),
x => x.SelectedTime, (x, v) => x.SelectedTime = v);

//Template Items
// Template Items
private TimePickerPresenter _presenter;
private Button _flyoutButton;
private Border _firstPickerHost;
private Border _secondPickerHost;
private Border _thirdPickerHost;
private TextBlock _hourText;
private TextBlock _minuteText;
public TextBlock _periodText;
private TextBlock _periodText;
private Rectangle _firstSplitter;
private Rectangle _secondSplitter;
private Grid _contentGrid;
Expand Down Expand Up @@ -145,7 +145,7 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
if (_flyoutButton != null)
_flyoutButton.Click -= OnFlyoutButtonClicked;

if(_presenter != null)
if (_presenter != null)
{
_presenter.Confirmed -= OnConfirmed;
_presenter.Dismissed -= OnDismissPicker;
Expand All @@ -170,7 +170,6 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
_popup = e.NameScope.Find<Popup>("Popup");
_presenter = e.NameScope.Find<TimePickerPresenter>("PickerPresenter");


if (_flyoutButton != null)
_flyoutButton.Click += OnFlyoutButtonClicked;

Expand All @@ -185,7 +184,6 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
_presenter[!TimePickerPresenter.MinuteIncrementProperty] = this[!MinuteIncrementProperty];
_presenter[!TimePickerPresenter.ClockIdentifierProperty] = this[!ClockIdentifierProperty];
}

}

private void SetGrid()
Expand All @@ -195,30 +193,19 @@ private void SetGrid()

bool use24HourClock = ClockIdentifier == "24HourClock";

if (!use24HourClock)
{
_contentGrid.ColumnDefinitions = new ColumnDefinitions("*,Auto,*,Auto,*");
_thirdPickerHost.IsVisible = true;
_secondSplitter.IsVisible = true;
var columnsD = use24HourClock ? "*, Auto, *" : "*, Auto, *, Auto, *";
_contentGrid.ColumnDefinitions = new ColumnDefinitions(columnsD);

Grid.SetColumn(_firstPickerHost, 0);
Grid.SetColumn(_secondPickerHost, 2);
Grid.SetColumn(_thirdPickerHost, 4);
_thirdPickerHost.IsVisible = !use24HourClock;
_secondSplitter.IsVisible = !use24HourClock;

Grid.SetColumn(_firstSplitter, 1);
Grid.SetColumn(_secondSplitter, 3);
}
else
{
_contentGrid.ColumnDefinitions = new ColumnDefinitions("*,Auto,*");
_thirdPickerHost.IsVisible = false;
_secondSplitter.IsVisible = false;
Grid.SetColumn(_firstPickerHost, 0);
Grid.SetColumn(_secondPickerHost, 2);

Grid.SetColumn(_firstPickerHost, 0);
Grid.SetColumn(_secondPickerHost, 2);
Grid.SetColumn(_thirdPickerHost, use24HourClock ? 0 : 4);

Grid.SetColumn(_firstSplitter, 1);
}
Grid.SetColumn(_firstSplitter, 1);
Grid.SetColumn(_secondSplitter, use24HourClock ? 0 : 3);
}

private void SetSelectedTimeText()
Expand All @@ -237,14 +224,13 @@ private void SetSelectedTimeText()
hr = hr > 12 ? hr - 12 : hr == 0 ? 12 : hr;
newTime = new TimeSpan(hr, newTime.Minutes, 0);
}
_hourText.Text = newTime.ToString("%h");

_hourText.Text = newTime.ToString("%h");
_minuteText.Text = newTime.ToString("mm");
PseudoClasses.Set(":hasnotime", false);

_periodText.Text = time.Value.Hours >= 12 ? CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator :
CultureInfo.CurrentCulture.DateTimeFormat.AMDesignator;

}
else
{
Expand All @@ -262,15 +248,15 @@ protected virtual void OnSelectedTimeChanged(TimeSpan? oldTime, TimeSpan? newTim
SelectedTimeChanged?.Invoke(this, new TimePickerSelectedValueChangedEventArgs(oldTime, newTime));
}

private void OnFlyoutButtonClicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
private void OnFlyoutButtonClicked(object sender, Interactivity.RoutedEventArgs e)
{
_presenter.Time = SelectedTime ?? DateTime.Now.TimeOfDay;

_popup.IsOpen = true;

var deltaY = _presenter.GetOffsetForPopup();

//The extra 5 px I think is related to default popup placement behavior
// The extra 5 px I think is related to default popup placement behavior
_popup.Host.ConfigurePosition(_popup.PlacementTarget, PlacementMode.AnchorAndGravity, new Point(0, deltaY + 5),
Primitives.PopupPositioning.PopupAnchor.Bottom, Primitives.PopupPositioning.PopupGravity.Bottom,
Primitives.PopupPositioning.PopupPositionerConstraintAdjustment.SlideY);
Expand All @@ -287,6 +273,5 @@ private void OnConfirmed(object sender, EventArgs e)
_popup.Close();
SelectedTime = _presenter.Time;
}

}
}
38 changes: 18 additions & 20 deletions src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public TimePickerPresenter()
KeyboardNavigation.SetTabNavigation(this, KeyboardNavigationMode.Cycle);
}

//TemplateItems
// TemplateItems
private Grid _pickerContainer;
private Button _acceptButton;
private Button _dismissButton;
Expand All @@ -55,8 +55,8 @@ public TimePickerPresenter()
private Button _minuteDownButton;
private Button _periodDownButton;

//Backing Fields
private TimeSpan _Time;
// Backing Fields
private TimeSpan _time;
private int _minuteIncrement = 1;
private string _clockIdentifier = "12HourClock";

Expand All @@ -83,7 +83,7 @@ public string ClockIdentifier
get => _clockIdentifier;
set
{
if (string.IsNullOrEmpty(value) || value == "" || !(value == "12HourClock" || value == "24HourClock"))
if (string.IsNullOrEmpty(value) || !(value == "12HourClock" || value == "24HourClock"))
throw new ArgumentException("Invalid ClockIdentifier");
SetAndRaise(ClockIdentifierProperty, ref _clockIdentifier, value);
InitPicker();
Expand All @@ -95,10 +95,10 @@ public string ClockIdentifier
/// </summary>
public TimeSpan Time
{
get => _Time;
get => _time;
set
{
SetAndRaise(TimeProperty, ref _Time, value);
SetAndRaise(TimeProperty, ref _time, value);
InitPicker();
}
}
Expand Down Expand Up @@ -213,26 +213,24 @@ private void InitPicker()

private void SetGrid()
{
if (ClockIdentifier == "12HourClock")
{
_pickerContainer.ColumnDefinitions = new ColumnDefinitions("*,Auto,*,Auto,*");
_spacer2.IsVisible = true;
_periodHost.IsVisible = true;
}
else
{
_pickerContainer.ColumnDefinitions = new ColumnDefinitions("*,Auto,*");
_spacer2.IsVisible = false;
_periodHost.IsVisible = false;
}
bool use24HourClock = ClockIdentifier == "24HourClock";

var columnsD = use24HourClock ? "*, Auto, *" : "*, Auto, *, Auto, *";
_pickerContainer.ColumnDefinitions = new ColumnDefinitions(columnsD);

_spacer2.IsVisible = !use24HourClock;
_periodHost.IsVisible = !use24HourClock;

Grid.SetColumn(_spacer2, use24HourClock ? 0 : 3);
Grid.SetColumn(_periodHost, use24HourClock ? 0 : 4);
}

private void OnDismissButtonClicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
private void OnDismissButtonClicked(object sender, RoutedEventArgs e)
{
OnDismiss();
}

private void OnAcceptButtonClicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
private void OnAcceptButtonClicked(object sender, RoutedEventArgs e)
{
OnConfirmed();
}
Expand Down

0 comments on commit 70a0f00

Please sign in to comment.