Browse Source

Merge pull request #7634 from AvaloniaUI/fixes/7633-date-time-picker-popup

Fix Date/Time picker popups
pull/7645/head
Max Katz 5 years ago
committed by GitHub
parent
commit
5d41ec76aa
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      src/Avalonia.Controls/DateTimePickers/DatePicker.cs
  2. 5
      src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs
  3. 23
      src/Avalonia.Controls/DateTimePickers/TimePicker.cs
  4. 5
      src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs

20
src/Avalonia.Controls/DateTimePickers/DatePicker.cs

@ -4,6 +4,7 @@ using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.Layout;
using System;
using System.Collections.Generic;
using System.Globalization;
@ -398,18 +399,27 @@ namespace Avalonia.Controls
private void OnFlyoutButtonClicked(object? sender, RoutedEventArgs e)
{
if (_presenter == null)
throw new InvalidOperationException("No DatePickerPresenter found");
throw new InvalidOperationException("No DatePickerPresenter found.");
if (_popup == null)
throw new InvalidOperationException("No Popup found.");
_presenter.Date = SelectedDate ?? DateTimeOffset.Now;
_popup!.IsOpen = true;
_popup.PlacementMode = PlacementMode.AnchorAndGravity;
_popup.PlacementAnchor = Primitives.PopupPositioning.PopupAnchor.Bottom;
_popup.PlacementGravity = Primitives.PopupPositioning.PopupGravity.Bottom;
_popup.PlacementConstraintAdjustment = Primitives.PopupPositioning.PopupPositionerConstraintAdjustment.SlideY;
_popup.IsOpen = true;
// Overlay popup hosts won't get measured until the next layout pass, but we need the
// template to be applied to `_presenter` now. Detect this case and force a layout pass.
if (!_presenter.IsMeasureValid)
(VisualRoot as ILayoutRoot)?.LayoutManager?.ExecuteInitialLayoutPass();
var deltaY = _presenter.GetOffsetForPopup();
// 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);
_popup.VerticalOffset = deltaY + 5;
}
protected virtual void OnSelectedDateChanged(object? sender, DatePickerSelectedValueChangedEventArgs e)

5
src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs

@ -537,8 +537,11 @@ namespace Avalonia.Controls
internal double GetOffsetForPopup()
{
if (_monthSelector is null)
return 0;
var acceptDismissButtonHeight = _acceptButton != null ? _acceptButton.Bounds.Height : 41;
return -(MaxHeight - acceptDismissButtonHeight) / 2 - (_monthSelector!.ItemHeight / 2);
return -(MaxHeight - acceptDismissButtonHeight) / 2 - (_monthSelector.ItemHeight / 2);
}
}
}

23
src/Avalonia.Controls/DateTimePickers/TimePicker.cs

@ -3,6 +3,7 @@ using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Layout;
using System;
using System.Globalization;
@ -254,16 +255,28 @@ namespace Avalonia.Controls
private void OnFlyoutButtonClicked(object? sender, Interactivity.RoutedEventArgs e)
{
_presenter!.Time = SelectedTime ?? DateTime.Now.TimeOfDay;
if (_presenter == null)
throw new InvalidOperationException("No DatePickerPresenter found.");
if (_popup == null)
throw new InvalidOperationException("No Popup found.");
_popup!.IsOpen = true;
_presenter.Time = SelectedTime ?? DateTime.Now.TimeOfDay;
_popup.PlacementMode = PlacementMode.AnchorAndGravity;
_popup.PlacementAnchor = Primitives.PopupPositioning.PopupAnchor.Bottom;
_popup.PlacementGravity = Primitives.PopupPositioning.PopupGravity.Bottom;
_popup.PlacementConstraintAdjustment = Primitives.PopupPositioning.PopupPositionerConstraintAdjustment.SlideY;
_popup.IsOpen = true;
// Overlay popup hosts won't get measured until the next layout pass, but we need the
// template to be applied to `_presenter` now. Detect this case and force a layout pass.
if (!_presenter.IsMeasureValid)
(VisualRoot as ILayoutRoot)?.LayoutManager?.ExecuteInitialLayoutPass();
var deltaY = _presenter.GetOffsetForPopup();
// 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);
_popup.VerticalOffset = deltaY + 5;
}
private void OnDismissPicker(object? sender, EventArgs e)

5
src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs

@ -256,8 +256,11 @@ namespace Avalonia.Controls
internal double GetOffsetForPopup()
{
if (_hourSelector is null)
return 0;
var acceptDismissButtonHeight = _acceptButton != null ? _acceptButton.Bounds.Height : 41;
return -(MaxHeight - acceptDismissButtonHeight) / 2 - (_hourSelector!.ItemHeight / 2);
return -(MaxHeight - acceptDismissButtonHeight) / 2 - (_hourSelector.ItemHeight / 2);
}
}
}

Loading…
Cancel
Save