Можно ли получить всплывающее окно для игнорирования MenuDropAlignment в приложении WPF / Touch?

как немного фона-Windows имеет средство для сенсорного / TabletPCs, посредством которого он сдвигает положение всплывающих окон/меню в зависимости от вашей "управляемости" (чтобы предотвратить появление меню под рукой).

по сути это если вы настроены на "правшей" (который, кажется, по умолчанию, как только вы подключили устройство с сенсорным), каждое всплывающее окно вы открываете искусственно ногами в левую сторону - это вызывает массивные проблемы макета, где мы пытаемся выстроить всплывающее окно с элементом "выскочил из" :

настройки планшетного ПК установлены на левую руку - нет искусственной коррекции из Windows Tablet PC Settings set to Left handed - no artificial correction from Windows

настройки планшетного ПК установлены на правую руку-Windows искусственно регулирует наше позиционирование Tablet PC Settings set to Right handed - Windows artificially adjusts our positioning

мы можем определить, что этот параметр имеет значение с SystemParameters.MenuDropAlignment, и для тривиальных всплывающих окон мы можем настроить это, используя фактическую ширину всплывающего окна, но для динамических всплывающих окон и когда мы бросаем справа налево поддержку в микс, это просто не работает.

В настоящее время кажется более вероятным, что нам придется пройти через каждое всплывающее окно, вручную разработать значение для настройки удара и добавить что-то вроде этого к каждому:

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Source={x:Static SystemParameters.MenuDropAlignment}}" Value="True"/>
        <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=FlowDirection}" Value="RightToLeft"/>
    </MultiDataTrigger.Conditions>
    <MultiDataTrigger.Setters>
        <Setter Property="HorizontalOffset" Value="-50"/> <!-- Set to arbitrary value to test -->
    </MultiDataTrigger.Setters>
</MultiDataTrigger>

Так.. вернемся к вопросу: -) кто-нибудь знает способ остановить всплывающее окно WPF, глядя на эту настройку вообще?

для тех, у кого нет сенсорного устройства, вы можете получить доступ к настройкам планшетного ПК бег:

C:Windowsexplorer.exe оболочки::: {80F3F1D5-FECA-45F3-BC32-752C152E456E}

и увидеть беспорядок, который он делает для себя : -)

4 ответов


Я написал пользовательское всплывающее окно, которое решает эту проблему: вы можете установить свойство зависимости ForceAlignment и открыть его с помощью метода "Open", или вы можете напрямую вызвать методы "OpenLeft" и "OpenRight".

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

установите его в обычный режим для всего вашего приложения:

FieldInfo fi = typeof(SystemParameters).GetField("_menuDropAlignment",
   BindingFlags.NonPublic | BindingFlags.Static);

fi.SetValue(null, false);

SystemParameters.MenuDropAlignment используется в одном методе:

System.Windows.Controls.Primitives.Popup.GetPointCombination()

это частный метод имеет логику, которая зависит от значения Popup.Placement типа PlacementMode:

public enum PlacementMode
{
    Absolute,
    Relative,
    Bottom,
    Center,
    Right,
    AbsolutePoint,
    RelativePoint,
    Mouse,
    MousePoint,
    Left,
    Top,
    Custom
}

на GetPointCombination(), он проверяет только MenuDropAlignment когда PlacementMode is Relative, AbsolutePoint, RelativePoint или MousePoint. Если вы можете использовать один из других PlacementModes тогда вы не будете объектом MenuDropAlignment проверка.

если вы используете PlacementMode.Custom, тогда вы также захотите установить Popup.CustomPopupPlacementCallback к действительному методу, чтобы предоставить всплывающее окно CustomPopupPlacement[] координаты.

Источник: Отражатель


казалось бы это просто невозможно, поэтому мы прибегаем к MultiDataTrigger в вопросе компенсации.