Browse Source

Fix date/time picker with overlay popups.

When using overlay popups, a measure won't be done immediately on open, so the presenter template won't be set. Force a layout pass in this case. Also add a null check in `GetOffsetForPopup` just in case it does happen by some chance elsewhere.

Fixes #7632
pull/7634/head
Steven Kirk 5 years ago
parent
commit
d117be4ec6
  1. 6
      src/Avalonia.Controls/DateTimePickers/DatePicker.cs
  2. 5
      src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs
  3. 6
      src/Avalonia.Controls/DateTimePickers/TimePicker.cs
  4. 5
      src/Avalonia.Controls/DateTimePickers/TimePickerPresenter.cs

6
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;
@ -410,6 +411,11 @@ namespace Avalonia.Controls
_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

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);
}
}
}

6
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;
@ -267,6 +268,11 @@ namespace Avalonia.Controls
_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

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