Is it possible to get a popup to ignore MenuDropAlignment in a WPF / Touch app?

前端 未结 5 2073
终归单人心
终归单人心 2021-02-04 05:26

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

相关标签:
5条回答
  • 2021-02-04 06:03

    Set it to regular mode for your whole application:

    FieldInfo fi = typeof(SystemParameters).GetField("_menuDropAlignment",
       BindingFlags.NonPublic | BindingFlags.Static);
    
    fi.SetValue(null, false);
    
    0 讨论(0)
  • 2021-02-04 06:06

    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

    0 讨论(0)
  • 2021-02-04 06:10

    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 :

    • True or False to your datatrigger value,
    • Left or Right as your setter value.

    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.

    0 讨论(0)
  • 2021-02-04 06:21

    It would appear this just isn't possible, so we are resorting to the MultiDataTrigger in the question to compensate.

    0 讨论(0)
  • 2021-02-04 06:22

    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
    
    0 讨论(0)
提交回复
热议问题