diff --git a/src/Perspex.Controls/DropDown.cs b/src/Perspex.Controls/DropDown.cs index 34a845d5c3..27cf8209d4 100644 --- a/src/Perspex.Controls/DropDown.cs +++ b/src/Perspex.Controls/DropDown.cs @@ -2,11 +2,9 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; -using System.Linq; using Perspex.Controls.Generators; using Perspex.Controls.Primitives; using Perspex.Controls.Shapes; -using Perspex.Controls.Templates; using Perspex.Input; using Perspex.Layout; using Perspex.Media; @@ -14,6 +12,10 @@ using Perspex.VisualTree; namespace Perspex.Controls { + + /// + /// A drop-down list control. + /// public class DropDown : SelectingItemsControl, IContentControl { public static readonly PerspexProperty ContentProperty = @@ -36,7 +38,6 @@ namespace Perspex.Controls private bool _isDropDownOpen; private Popup _popup; - private bool _closing; static DropDown() { @@ -73,7 +74,7 @@ namespace Perspex.Controls set { SetAndRaise(IsDropDownOpenProperty, ref _isDropDownOpen, value); } } - public object SelectionBoxItem + protected object SelectionBoxItem { get { return GetValue(SelectionBoxItemProperty); } set { SetValue(SelectionBoxItemProperty, value); } @@ -112,18 +113,17 @@ namespace Perspex.Controls protected override void OnPointerPressed(PointerPressEventArgs e) { - if (!IsDropDownOpen && !_closing && ((IVisual)e.Source).GetVisualRoot() != typeof(PopupRoot)) + if (!IsDropDownOpen && ((IVisual)e.Source).GetVisualRoot() != typeof(PopupRoot)) { IsDropDownOpen = true; e.Handled = true; } - _closing = false; - if (!e.Handled) { if (UpdateSelectionFromEventSource(e.Source)) { + _popup?.Close(); e.Handled = true; } } @@ -140,7 +140,6 @@ namespace Perspex.Controls _popup = e.NameScope.Get("PART_Popup"); _popup.Opened += PopupOpened; - _popup.Closed += PopupClosed; } private void PopupOpened(object sender, EventArgs e) @@ -154,11 +153,6 @@ namespace Perspex.Controls } } - private void PopupClosed(object sender, EventArgs e) - { - _closing = true; - } - private void SelectedItemChanged(PerspexPropertyChangedEventArgs e) { UpdateSelectionBoxItem(e.NewValue); diff --git a/src/Perspex.Controls/Primitives/Popup.cs b/src/Perspex.Controls/Primitives/Popup.cs index 74459ed4c4..ae6291aa17 100644 --- a/src/Perspex.Controls/Primitives/Popup.cs +++ b/src/Perspex.Controls/Primitives/Popup.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using Perspex.Input; using Perspex.Interactivity; using Perspex.Metadata; using Perspex.Rendering; @@ -171,12 +172,11 @@ namespace Perspex.Controls.Primitives } _popupRoot.Position = GetPosition(); - _popupRoot.AddHandler(PointerPressedEvent, MaybeClose, RoutingStrategies.Bubble, true); if (_topLevel != null) { - _topLevel.Deactivated += MaybeClose; - _topLevel.AddHandler(PointerPressedEvent, MaybeClose, RoutingStrategies.Tunnel); + _topLevel.Deactivated += TopLevelDeactivated; + _topLevel.AddHandler(PointerPressedEvent, PointerPressedOutside, RoutingStrategies.Tunnel); } PopupRootCreated?.Invoke(this, EventArgs.Empty); @@ -193,9 +193,8 @@ namespace Perspex.Controls.Primitives { if (_popupRoot != null) { - _popupRoot.PointerPressed -= MaybeClose; - _topLevel.RemoveHandler(PointerPressedEvent, MaybeClose); - _topLevel.Deactivated -= MaybeClose; + _topLevel.RemoveHandler(PointerPressedEvent, PointerPressedOutside); + _topLevel.Deactivated -= TopLevelDeactivated; _popupRoot.Hide(); } @@ -292,23 +291,23 @@ namespace Perspex.Controls.Primitives } } - /// - /// 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) + private void PointerPressedOutside(object sender, PointerPressEventArgs e) { - var routed = e as RoutedEventArgs; - var outside = true; - - if (routed != null) + if (!StaysOpen) { - outside = ((IVisual)routed.Source).GetVisualRoot() != this.PopupRoot; + var root = ((IVisual)e.Source).GetVisualRoot(); + + if (root != this.PopupRoot) + { + Close(); + e.Handled = true; + } } + } - if (outside && !StaysOpen) + private void TopLevelDeactivated(object sender, EventArgs e) + { + if (!StaysOpen) { Close(); }