Is it possible to get a popup to ignore MenuDropAlignment in a WPF / Touch app?
I wrote a custom popup that solve this problem: you can set the ForceAlignment dependency property and open it with the "Open" method, or you can directly call "OpenLeft" and "OpenRight" methods.
Public Class CustomPopupInherits Primitives.PopupPrivate Shared moFI As Reflection.FieldInfo = GetType(SystemParameters).GetField("_menuDropAlignment", Reflection.BindingFlags.NonPublic + Reflection.BindingFlags.Static)Public Enum enuForceAlignment None = 0 Left RightEnd EnumPublic Property ForceAlignment As enuForceAlignment Get Return GetValue(ForceAlignmentProperty) End Get Set(ByVal value As enuForceAlignment) SetValue(ForceAlignmentProperty, value) End SetEnd PropertyPublic Shared ReadOnly ForceAlignmentProperty As DependencyProperty = _ DependencyProperty.Register("ForceAlignment", _ GetType(enuForceAlignment), GetType(CustomPopup), _ New FrameworkPropertyMetadata(enuForceAlignment.None))Public Sub Open() Select Case ForceAlignment Case enuForceAlignment.Left OpenLeft() Case enuForceAlignment.Right OpenRight() Case Else IsOpen = True End SelectEnd SubPublic Sub OpenRight() _Open(False)End SubPublic Sub OpenLeft() _Open(True)End SubPrivate Sub _Open(paMenuDropAlignment As Boolean) If SystemParameters.MenuDropAlignment <> paMenuDropAlignment Then moFI.SetValue(Nothing, paMenuDropAlignment) IsOpen = True moFI.SetValue(Nothing, Not paMenuDropAlignment) Else IsOpen = True End IfEnd SubEnd Class
Set it to regular mode for your whole application:
FieldInfo fi = typeof(SystemParameters).GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);fi.SetValue(null, false);
SystemParameters.MenuDropAlignment
is used in a single method:
System.Windows.Controls.Primitives.Popup.GetPointCombination()
This private method has logic that depends upon the value of Popup.Placement
, which is of type PlacementMode
:
public enum PlacementMode{ Absolute, Relative, Bottom, Center, Right, AbsolutePoint, RelativePoint, Mouse, MousePoint, Left, Top, Custom}
In GetPointCombination()
, it only checks the MenuDropAlignment
when the PlacementMode
is Relative
, AbsolutePoint
, RelativePoint
, or MousePoint
. If you can use one of the other PlacementModes
then you won't be subject to the MenuDropAlignment
check.
If you use PlacementMode.Custom
, then you'll also want to set the Popup.CustomPopupPlacementCallback
to a valid method in order to provide your popup's CustomPopupPlacement[]
coordinates.
Source: Reflector