Skip to content

Commit 53efa7c

Browse files
committed
Proposed fix for #703.
The popup is not properly repositioning itself when its anchor control is moved. This updates the popup's position whenever the position between the two has changed.
1 parent 54ddefa commit 53efa7c

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

MaterialDesignThemes.Wpf/PopupBox.cs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
using System;
1+
using ControlzEx;
2+
using System;
23
using System.ComponentModel;
3-
using System.Diagnostics;
44
using System.Linq;
55
using System.Runtime.InteropServices;
6-
using System.Text;
7-
using System.Threading.Tasks;
86
using System.Windows;
97
using System.Windows.Controls;
108
using System.Windows.Controls.Primitives;
119
using System.Windows.Input;
1210
using System.Windows.Markup;
1311
using System.Windows.Media;
1412
using System.Windows.Media.Animation;
15-
using ControlzEx;
1613

1714
namespace MaterialDesignThemes.Wpf
1815
{
@@ -110,13 +107,19 @@ public class PopupBox : ContentControl
110107
private ContentControl _popupContentControl;
111108
private ToggleButton _toggleButton;
112109
private Point _popupPointFromLastRequest;
110+
private Point _lastRelativePositon;
113111

114112
static PopupBox()
115113
{
116114
DefaultStyleKeyProperty.OverrideMetadata(typeof(PopupBox), new FrameworkPropertyMetadata(typeof(PopupBox)));
117115
ToolTipService.IsEnabledProperty.OverrideMetadata(typeof(PopupBox), new FrameworkPropertyMetadata(null, CoerceToolTipIsEnabled));
118116
EventManager.RegisterClassHandler(typeof(PopupBox), Mouse.LostMouseCaptureEvent, new MouseEventHandler(OnLostMouseCapture));
119-
EventManager.RegisterClassHandler(typeof(PopupBox), Mouse.MouseDownEvent, new MouseButtonEventHandler(OnMouseButtonDown), true);
117+
EventManager.RegisterClassHandler(typeof(PopupBox), Mouse.MouseDownEvent, new MouseButtonEventHandler(OnMouseButtonDown), true);
118+
}
119+
120+
public PopupBox()
121+
{
122+
LayoutUpdated += OnLayoutUpdated;
120123
}
121124

122125
public static readonly DependencyProperty ToggleContentProperty = DependencyProperty.Register(
@@ -229,8 +232,8 @@ private static void IsPopupOpenPropertyChangedCallback(DependencyObject dependen
229232
else
230233
Mouse.Capture(null);
231234
}
232-
233-
popupBox.AnimateChildrenIn(!newValue);
235+
236+
popupBox.AnimateChildrenIn(!newValue);
234237
popupBox._popup?.RefreshPosition();
235238

236239
VisualStateManager.GoToState(popupBox, newValue ? PopupIsOpenStateName : PopupIsClosedStateName, true);
@@ -239,7 +242,6 @@ private static void IsPopupOpenPropertyChangedCallback(DependencyObject dependen
239242
popupBox.OnOpened();
240243
else
241244
popupBox.OnClosed();
242-
243245
}
244246

245247
/// <summary>
@@ -398,7 +400,7 @@ public override void OnApplyTemplate()
398400
if (_popup != null)
399401
_popup.Loaded += PopupOnLoaded;
400402
if (_toggleButton != null)
401-
_toggleButton.PreviewMouseLeftButtonUp += ToggleButtonOnPreviewMouseLeftButtonUp;
403+
_toggleButton.PreviewMouseLeftButtonUp += ToggleButtonOnPreviewMouseLeftButtonUp;
402404

403405
VisualStateManager.GoToState(this, IsPopupOpen ? PopupIsOpenStateName : PopupIsClosedStateName, false);
404406
}
@@ -408,7 +410,7 @@ protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChanged
408410
base.OnIsKeyboardFocusWithinChanged(e);
409411

410412
if (IsPopupOpen && !IsKeyboardFocusWithin)
411-
{
413+
{
412414
Close();
413415
}
414416
}
@@ -439,9 +441,22 @@ protected override void OnMouseEnter(MouseEventArgs e)
439441

440442
SetCurrentValue(IsPopupOpenProperty, true);
441443
}
442-
443444
base.OnMouseEnter(e);
444445
}
446+
447+
private void OnLayoutUpdated(object sender, EventArgs eventArgs)
448+
{
449+
if (_popupContentControl != null && _popup != null &&
450+
(PopupMode == PopupBoxPopupMode.MouseOver || PopupMode == PopupBoxPopupMode.MouseOverEager))
451+
{
452+
Point relativePosition = _popupContentControl.TranslatePoint(new Point(), this);
453+
if (relativePosition != _lastRelativePositon)
454+
{
455+
_popup.RefreshPosition();
456+
_lastRelativePositon = _popupContentControl.TranslatePoint(new Point(), this);
457+
}
458+
}
459+
}
445460

446461
protected override void OnMouseLeave(MouseEventArgs e)
447462
{
@@ -461,16 +476,16 @@ protected void Close()
461476

462477
private CustomPopupPlacement[] GetPopupPlacement(Size popupSize, Size targetSize, Point offset)
463478
{
464-
double x, y;
465-
479+
double x, y;
480+
466481
if (FlowDirection == FlowDirection.RightToLeft)
467482
offset.X += targetSize.Width / 2;
468-
483+
469484
switch (PlacementMode)
470485
{
471486
case PopupBoxPlacementMode.BottomAndAlignLeftEdges:
472487
x = 0 - Math.Abs(offset.X*3);
473-
y = targetSize.Height - Math.Abs(offset.Y);
488+
y = targetSize.Height - Math.Abs(offset.Y);
474489
break;
475490
case PopupBoxPlacementMode.BottomAndAlignRightEdges:
476491
x = 0 - popupSize.Width + targetSize.Width - offset.X;
@@ -699,7 +714,7 @@ private static void OnMouseButtonDown(object sender, MouseButtonEventArgs e)
699714
}
700715

701716
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
702-
{
717+
{
703718
if (IsPopupOpen && !StaysOpen)
704719
{
705720
Close();
@@ -735,7 +750,7 @@ private void ToggleButtonOnPreviewMouseLeftButtonUp(object sender, MouseButtonEv
735750

736751
Close();
737752
Mouse.Capture(null);
738-
mouseButtonEventArgs.Handled = true;
753+
mouseButtonEventArgs.Handled = true;
739754
}
740755

741756
private static object CoerceToolTipIsEnabled(DependencyObject dependencyObject, object value)

0 commit comments

Comments
 (0)