|
|
|
@ -40,6 +40,12 @@ namespace Avalonia.Controls.Primitives |
|
|
|
public static readonly StyledProperty<PlacementMode> PlacementModeProperty = |
|
|
|
AvaloniaProperty.Register<Popup, PlacementMode>(nameof(PlacementMode), defaultValue: PlacementMode.Bottom); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="ObeyScreenEdges"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly StyledProperty<bool> ObeyScreenEdgesProperty = |
|
|
|
AvaloniaProperty.Register<Popup, bool>(nameof(ObeyScreenEdges)); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="HorizontalOffset"/> property.
|
|
|
|
/// </summary>
|
|
|
|
@ -136,6 +142,16 @@ namespace Avalonia.Controls.Primitives |
|
|
|
set { SetValue(PlacementModeProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets a value indicating whether the popup positions itself within the nearest screen boundary
|
|
|
|
/// when its opened at a position where it would otherwise overlap the screen edge.
|
|
|
|
/// </summary>
|
|
|
|
public bool ObeyScreenEdges |
|
|
|
{ |
|
|
|
get => GetValue(ObeyScreenEdgesProperty); |
|
|
|
set => SetValue(ObeyScreenEdgesProperty, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the Horizontal offset of the popup in relation to the <see cref="PlacementTarget"/>
|
|
|
|
/// </summary>
|
|
|
|
@ -216,12 +232,12 @@ namespace Avalonia.Controls.Primitives |
|
|
|
var window = _topLevel as Window; |
|
|
|
if (window != null) |
|
|
|
{ |
|
|
|
window.Deactivated += WindowDeactivated; |
|
|
|
window.Deactivated += WindowDeactivated; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
var parentPopuproot = _topLevel as PopupRoot; |
|
|
|
if(parentPopuproot != null && parentPopuproot.Parent!=null) |
|
|
|
if (parentPopuproot != null && parentPopuproot.Parent != null) |
|
|
|
{ |
|
|
|
((Popup)(parentPopuproot.Parent)).Closed += ParentClosed; |
|
|
|
} |
|
|
|
@ -234,13 +250,18 @@ namespace Avalonia.Controls.Primitives |
|
|
|
|
|
|
|
_popupRoot.Show(); |
|
|
|
|
|
|
|
if (ObeyScreenEdges) |
|
|
|
{ |
|
|
|
_popupRoot.SnapInsideScreenEdges(); |
|
|
|
} |
|
|
|
|
|
|
|
_ignoreIsOpenChanged = true; |
|
|
|
IsOpen = true; |
|
|
|
_ignoreIsOpenChanged = false; |
|
|
|
|
|
|
|
Opened?.Invoke(this, EventArgs.Empty); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Closes the popup.
|
|
|
|
/// </summary>
|
|
|
|
@ -346,8 +367,10 @@ namespace Avalonia.Controls.Primitives |
|
|
|
/// <returns>The popup's position in screen coordinates.</returns>
|
|
|
|
protected virtual Point GetPosition() |
|
|
|
{ |
|
|
|
return GetPosition(PlacementTarget ?? this.GetVisualParent<Control>(), PlacementMode, PopupRoot, |
|
|
|
var result = GetPosition(PlacementTarget ?? this.GetVisualParent<Control>(), PlacementMode, PopupRoot, |
|
|
|
HorizontalOffset, VerticalOffset); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
internal static Point GetPosition(Control target, PlacementMode placement, PopupRoot popupRoot, double horizontalOffset, double verticalOffset) |
|
|
|
@ -399,8 +422,8 @@ namespace Avalonia.Controls.Primitives |
|
|
|
{ |
|
|
|
if (!StaysOpen) |
|
|
|
{ |
|
|
|
if(!IsChildOrThis((IVisual)e.Source)) |
|
|
|
{ |
|
|
|
if (!IsChildOrThis((IVisual)e.Source)) |
|
|
|
{ |
|
|
|
Close(); |
|
|
|
e.Handled = true; |
|
|
|
} |
|
|
|
@ -412,12 +435,12 @@ namespace Avalonia.Controls.Primitives |
|
|
|
IVisual root = child.GetVisualRoot(); |
|
|
|
while (root is PopupRoot) |
|
|
|
{ |
|
|
|
if (root == PopupRoot) return true; |
|
|
|
if (root == PopupRoot) return true; |
|
|
|
root = ((PopupRoot)root).Parent.GetVisualRoot(); |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void WindowDeactivated(object sender, EventArgs e) |
|
|
|
{ |
|
|
|
if (!StaysOpen) |
|
|
|
|