As a bit of background - Windows has a facility for Touch/TabletPCs whereby it shifts the position of popups/menus depending on your \"handedness\" (to prevent the menu appearin
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
This is pretty old but I found another way if you have .net 4.5 at least.
By overriding your menuitem/popup templates, you can use the following trigger:
<DataTrigger Binding="{Binding Path=(SystemParameters.MenuDropAlignment)}" Value="[True/False]">
<Setter TargetName="Popup" Property="Placement" Value="[Left/Right]"/>
</DataTrigger>
Off course, set the following :
It's important that the binding use Binding Path=() syntax and not Binding={x:static ...} so that you can use the StaticPropertyChanged event from your static class.
It would appear this just isn't possible, so we are resorting to the MultiDataTrigger in the question to compensate.
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 CustomPopup
Inherits Primitives.Popup
Private Shared moFI As Reflection.FieldInfo = GetType(SystemParameters).GetField("_menuDropAlignment", Reflection.BindingFlags.NonPublic + Reflection.BindingFlags.Static)
Public Enum enuForceAlignment
None = 0
Left
Right
End Enum
Public Property ForceAlignment As enuForceAlignment
Get
Return GetValue(ForceAlignmentProperty)
End Get
Set(ByVal value As enuForceAlignment)
SetValue(ForceAlignmentProperty, value)
End Set
End Property
Public 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 Select
End Sub
Public Sub OpenRight()
_Open(False)
End Sub
Public Sub OpenLeft()
_Open(True)
End Sub
Private 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 If
End Sub
End Class