diff --git a/Perspex.Controls/Perspex.Controls.csproj b/Perspex.Controls/Perspex.Controls.csproj
index 763a0e5c58..5bcb9abb4f 100644
--- a/Perspex.Controls/Perspex.Controls.csproj
+++ b/Perspex.Controls/Perspex.Controls.csproj
@@ -50,6 +50,7 @@
+
diff --git a/Perspex.Controls/PlacementMode.cs b/Perspex.Controls/PlacementMode.cs
new file mode 100644
index 0000000000..89e848177a
--- /dev/null
+++ b/Perspex.Controls/PlacementMode.cs
@@ -0,0 +1,14 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2015 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Controls
+{
+ public enum PlacementMode
+ {
+ Bottom,
+ Right,
+ }
+}
diff --git a/Perspex.Controls/Popup.cs b/Perspex.Controls/Popup.cs
index a54518fb4d..3924bd38ec 100644
--- a/Perspex.Controls/Popup.cs
+++ b/Perspex.Controls/Popup.cs
@@ -10,6 +10,7 @@ namespace Perspex.Controls
using Perspex.Interactivity;
using Perspex.Platform;
using Perspex.Rendering;
+ using Perspex.VisualTree;
public class Popup : Control
{
@@ -19,6 +20,9 @@ namespace Perspex.Controls
public static readonly PerspexProperty IsOpenProperty =
PerspexProperty.Register("IsOpen");
+ public static readonly PerspexProperty PlacementModeProperty =
+ PerspexProperty.Register("PlacementMode", defaultValue: PlacementMode.Bottom);
+
public static readonly PerspexProperty PlacementTargetProperty =
PerspexProperty.Register("PlacementTarget");
@@ -61,6 +65,12 @@ namespace Perspex.Controls
set { this.SetValue(IsOpenProperty, value); }
}
+ public PlacementMode PlacementMode
+ {
+ get { return this.GetValue(PlacementModeProperty); }
+ set { this.SetValue(PlacementModeProperty, value); }
+ }
+
public Control PlacementTarget
{
get { return this.GetValue(PlacementTargetProperty); }
@@ -130,9 +140,24 @@ namespace Perspex.Controls
private Point GetPosition()
{
- if (this.PlacementTarget != null)
+ var target = this.PlacementTarget ?? this.GetVisualParent();
+ Point point;
+
+ switch (this.PlacementMode)
+ {
+ case PlacementMode.Bottom:
+ point = target.Bounds.BottomLeft;
+ break;
+ case PlacementMode.Right:
+ point = target.Bounds.TopRight;
+ break;
+ default:
+ throw new InvalidOperationException("Invalid value for Popup.PlacementMode");
+ }
+
+ if (target != null)
{
- return this.PlacementTarget.PointToScreen(new Point(0, this.PlacementTarget.Bounds.Size.Height));
+ return target.PointToScreen(point);
}
else
{
diff --git a/Perspex.Themes.Default/MenuItemStyle.cs b/Perspex.Themes.Default/MenuItemStyle.cs
index 6ec245baef..b22cf9d391 100644
--- a/Perspex.Themes.Default/MenuItemStyle.cs
+++ b/Perspex.Themes.Default/MenuItemStyle.cs
@@ -188,6 +188,7 @@ namespace Perspex.Themes.Default
(popup = new Popup
{
Name = "popup",
+ PlacementMode = PlacementMode.Right,
StaysOpen = true,
[!!Popup.IsOpenProperty] = control[!!MenuItem.IsSubMenuOpenProperty],
Child = new Border