作为一个背景--Windows有一个Touch / TabletPCs设施,它根据你的“用手”改变弹出菜单/菜单的位置(以防止菜单出现在你的手下)。
基本上它的作用是如果你被设置为“右手”(它似乎默认为你连接了一个触摸设备),你打开的每个弹出窗口被人为地踢到左边 - 这会导致大量的布局问题我们尝试将弹出窗口与“弹出”项目对齐:
平板电脑设置设为左手 - 无法从Windows进行人工修正
平板电脑设置设置为右手 - Windows人工调整我们的定位
我们可以使用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弹出窗口看这个设置?
对于那些没有触控设备的人,您可以通过以下方式访问Tablet PC设置:
C:\ Windows \ explorer.exe shell ::: {80F3F1D5-FECA-45F3-BC32-752C152E456E}
看看它为自己造成的混乱: - )
答案 0 :(得分:3)
我编写了一个解决此问题的自定义弹出窗口:您可以设置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
答案 1 :(得分:3)
将其设置为整个应用程序的常规模式:
FieldInfo fi = typeof(SystemParameters).GetField("_menuDropAlignment",
BindingFlags.NonPublic | BindingFlags.Static);
fi.SetValue(null, false);
答案 2 :(得分:0)
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
为Relative
,AbsolutePoint
,RelativePoint
或{{1}时检查MousePoint
}。如果您可以使用其中一个PlacementModes
,则不会受到MenuDropAlignment
检查。
如果您使用PlacementMode.Custom
,那么您还需要将Popup.CustomPopupPlacementCallback
设置为有效方法,以便提供弹出窗口的CustomPopupPlacement[]
坐标。
来源:反射器
答案 3 :(得分:0)
这已经很老了,但是如果您至少拥有.net 4.5,我发现了另一种方法。
通过覆盖菜单项/弹出模板,您可以使用以下触发器:
<DataTrigger Binding="{Binding Path=(SystemParameters.MenuDropAlignment)}" Value="[True/False]">
<Setter TargetName="Popup" Property="Placement" Value="[Left/Right]"/>
</DataTrigger>
当然,请设置以下内容:
重要的是,绑定使用Binding Path =()语法而不是Binding = {x:static ...},以便您可以使用静态类中的StaticPropertyChanged事件。
答案 4 :(得分:-1)
看起来这是不可能的,所以我们在问题中使用MultiDataTrigger进行补偿。