diff --git a/Perspex.Controls/Popup.cs b/Perspex.Controls/Popup.cs
index d7aedb3a89..2eb886f5a3 100644
--- a/Perspex.Controls/Popup.cs
+++ b/Perspex.Controls/Popup.cs
@@ -12,90 +12,159 @@ namespace Perspex.Controls
using Perspex.Rendering;
using Perspex.VisualTree;
+ ///
+ /// Displays a popup window.
+ ///
public class Popup : Control, ILogical, IVisualTreeHost
{
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty ChildProperty =
- PerspexProperty.Register("Child");
+ PerspexProperty.Register(nameof(Child));
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty IsOpenProperty =
- PerspexProperty.Register("IsOpen");
+ PerspexProperty.Register(nameof(IsOpen));
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty PlacementModeProperty =
- PerspexProperty.Register("PlacementMode", defaultValue: PlacementMode.Bottom);
+ PerspexProperty.Register(nameof(PlacementMode), defaultValue: PlacementMode.Bottom);
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty PlacementTargetProperty =
- PerspexProperty.Register("PlacementTarget");
+ PerspexProperty.Register(nameof(PlacementTarget));
+ ///
+ /// Defines the property.
+ ///
public static readonly PerspexProperty StaysOpenProperty =
- PerspexProperty.Register("StaysOpen", true);
+ PerspexProperty.Register(nameof(StaysOpen), true);
+ ///
+ /// The root of the popup.
+ ///
private PopupRoot popupRoot;
+ ///
+ /// The top level control of the Popup's visual tree.
+ ///
private TopLevel topLevel;
+ ///
+ /// The popup's logical child.
+ ///
private PerspexSingleItemList logicalChild = new PerspexSingleItemList();
+ ///
+ /// Initializes static members of the class.
+ ///
static Popup()
{
- IsOpenProperty.Changed.Subscribe(IsOpenChanged);
+ IsOpenProperty.Changed.AddClassHandler(x => x.IsOpenChanged);
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
public Popup()
{
- this.GetObservableWithHistory(ChildProperty).Subscribe(ChildChanged);
+ this.GetObservableWithHistory(ChildProperty).Subscribe(this.ChildChanged);
}
+ ///
+ /// Raised when the popup closes.
+ ///
public event EventHandler Closed;
+ ///
+ /// Raised when the popup opens.
+ ///
public event EventHandler Opened;
+ ///
+ /// Raised when the popup root has been created, but before it has been shown.
+ ///
public event EventHandler PopupRootCreated;
+ ///
+ /// Gets or sets the control to display in the popup.
+ ///
public Control Child
{
get { return this.GetValue(ChildProperty); }
set { this.SetValue(ChildProperty, value); }
}
+ ///
+ /// Gets or sets a value indicating whether the popup is currently open.
+ ///
public bool IsOpen
{
get { return this.GetValue(IsOpenProperty); }
set { this.SetValue(IsOpenProperty, value); }
}
+ ///
+ /// Gets or sets the placement mode of the popup in relation to the .
+ ///
public PlacementMode PlacementMode
{
get { return this.GetValue(PlacementModeProperty); }
set { this.SetValue(PlacementModeProperty, value); }
}
+ ///
+ /// Gets or sets the control that is used to determine the popup's position.
+ ///
public Control PlacementTarget
{
get { return this.GetValue(PlacementTargetProperty); }
set { this.SetValue(PlacementTargetProperty, value); }
}
+ ///
+ /// Gets the root of the popup window.
+ ///
public PopupRoot PopupRoot
{
get { return this.popupRoot; }
}
+ ///
+ /// Gets or sets a value indicating whether the popup should stay open when the popup loses focus.
+ ///
public bool StaysOpen
{
get { return this.GetValue(StaysOpenProperty); }
set { this.SetValue(StaysOpenProperty, value); }
}
+ ///
+ /// Gets the logical children of the popup.
+ ///
IPerspexReadOnlyList ILogical.LogicalChildren
{
get { return this.logicalChild; }
}
+ ///
+ /// Gets the root of the popup window.
+ ///
IVisual IVisualTreeHost.Root
{
get { return this.popupRoot; }
}
+ ///
+ /// Opens the popup.
+ ///
public void Open()
{
if (this.popupRoot == null)
@@ -125,6 +194,9 @@ namespace Perspex.Controls
this.Opened?.Invoke(this, EventArgs.Empty);
}
+ ///
+ /// Closes the popup.
+ ///
public void Close()
{
if (this.popupRoot != null)
@@ -139,40 +211,56 @@ namespace Perspex.Controls
this.Closed?.Invoke(this, EventArgs.Empty);
}
+ ///
+ /// Measures the control.
+ ///
+ /// The available size for the control.
+ /// A size of 0,0 as Popup itself takes up no space.
protected override Size MeasureCore(Size availableSize)
{
return new Size();
}
+ ///
+ /// Called when the control is added to the visual tree.
+ ///
+ /// THe root of the visual tree.
protected override void OnAttachedToVisualTree(IRenderRoot root)
{
base.OnAttachedToVisualTree(root);
this.topLevel = root as TopLevel;
}
- protected override void OnDetachedFromVisualTree(IRenderRoot oldRoot)
+ ///
+ /// Called when the control is removed to the visual tree.
+ ///
+ /// THe root of the visual tree.
+ protected override void OnDetachedFromVisualTree(IRenderRoot root)
{
- base.OnDetachedFromVisualTree(oldRoot);
+ base.OnDetachedFromVisualTree(root);
this.topLevel = null;
}
- private static void IsOpenChanged(PerspexPropertyChangedEventArgs e)
+ ///
+ /// Called when the property changes.
+ ///
+ /// The event args.
+ private void IsOpenChanged(PerspexPropertyChangedEventArgs e)
{
- Popup popup = e.Sender as Popup;
-
- if (popup != null)
+ if ((bool)e.NewValue)
{
- if ((bool)e.NewValue)
- {
- popup.Open();
- }
- else
- {
- popup.Close();
- }
+ this.Open();
+ }
+ else
+ {
+ this.Close();
}
}
+ ///
+ /// Called when the property changes.
+ ///
+ /// The old and new values.
private void ChildChanged(Tuple values)
{
if (values.Item1 != null)
@@ -188,6 +276,10 @@ namespace Perspex.Controls
this.logicalChild.SingleItem = values.Item2;
}
+ ///
+ /// Gets the position for the popup based on the placement properties.
+ ///
+ /// The popup's position in screen coordinates.
private Point GetPosition()
{
var target = this.PlacementTarget ?? this.GetVisualParent();
@@ -215,6 +307,12 @@ namespace Perspex.Controls
}
}
+ ///
+ /// Conditionally closes the popup in response to an event, based on the value of the
+ /// property.
+ ///
+ /// The event sender.
+ /// The event args.
private void MaybeClose(object sender, EventArgs e)
{
if (!this.StaysOpen)
diff --git a/Perspex.Controls/PopupRoot.cs b/Perspex.Controls/PopupRoot.cs
index 05309e4647..ec6cc28b8e 100644
--- a/Perspex.Controls/PopupRoot.cs
+++ b/Perspex.Controls/PopupRoot.cs
@@ -12,40 +12,68 @@ namespace Perspex.Controls
using Perspex.Platform;
using Splat;
+ ///
+ /// The root window of a .
+ ///
public class PopupRoot : TopLevel, IInteractive
{
+ ///
+ /// Initializes static members of the class.
+ ///
static PopupRoot()
{
BackgroundProperty.OverrideDefaultValue(typeof(PopupRoot), Brushes.White);
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
public PopupRoot()
: base(Locator.Current.GetService())
{
this.GetObservable(ParentProperty).Subscribe(x => this.InheritanceParent = x);
}
+ ///
+ /// Gets the platform-specific window implementation.
+ ///
public new IPopupImpl PlatformImpl
{
get { return (IPopupImpl)base.PlatformImpl; }
}
+ ///
+ /// Gets the parent control in the event route.
+ ///
+ ///
+ /// Popup events are passed to their parent window. This facilitates this.
+ ///
IInteractive IInteractive.InteractiveParent
{
get { return this.Parent; }
}
+ ///
+ /// Sets the position of the popup in screen coordinates.
+ ///
+ /// The position.
public void SetPosition(Point p)
{
this.PlatformImpl.SetPosition(p);
}
+ ///
+ /// Hides the popup.
+ ///
public void Hide()
{
this.PlatformImpl.Hide();
this.IsVisible = false;
}
+ ///
+ /// Shows the popup.
+ ///
public void Show()
{
this.PlatformImpl.Show();