Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在WPF/Touch应用程序中获得忽略菜单对齐的弹出窗口?_Wpf_Xaml_Touch_Multi Touch_Multidatatrigger - Fatal编程技术网

是否可以在WPF/Touch应用程序中获得忽略菜单对齐的弹出窗口?

是否可以在WPF/Touch应用程序中获得忽略菜单对齐的弹出窗口?,wpf,xaml,touch,multi-touch,multidatatrigger,Wpf,Xaml,Touch,Multi Touch,Multidatatrigger,作为一个背景,Windows有一个触摸/桌面电脑的功能,它可以根据你的“用手习惯”(防止菜单出现在你的手下)改变弹出窗口/菜单的位置 基本上,如果您被设置为“右撇子”(这似乎默认为一旦您连接了触摸设备),则您打开的每个弹出窗口都会被人为踢向左侧-这会导致大量布局问题,我们尝试将弹出窗口与“弹出的”项对齐: 平板电脑设置设置为左手-无需通过Windows进行人工校正 平板电脑设置设置为右手-Windows人工调整我们的位置 我们可以检测这个设置是如何设置的,对于普通的弹出窗口,我们可以使用弹出

作为一个背景,Windows有一个触摸/桌面电脑的功能,它可以根据你的“用手习惯”(防止菜单出现在你的手下)改变弹出窗口/菜单的位置

基本上,如果您被设置为“右撇子”(这似乎默认为一旦您连接了触摸设备),则您打开的每个弹出窗口都会被人为踢向左侧-这会导致大量布局问题,我们尝试将弹出窗口与“弹出的”项对齐:

平板电脑设置设置为左手-无需通过Windows进行人工校正

平板电脑设置设置为右手-Windows人工调整我们的位置

我们可以检测这个设置是如何设置的,对于普通的弹出窗口,我们可以使用弹出窗口的实际宽度来调整它——但是对于动态弹出窗口,当我们在混合中加入从右到左的支持时,这根本不起作用

目前看来,我们很有可能需要查看每个弹出窗口,手动计算出一个值来调整踢击,并在每个弹出窗口中添加类似的内容:

<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}


看看它给你自己造成的混乱:-)

系统参数。MenuDropAlignment
用于一种方法:

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

此私有方法的逻辑取决于类型为
PlacementMode
Popup.Placement
的值:

public enum PlacementMode
{
    Absolute,
    Relative,
    Bottom,
    Center,
    Right,
    AbsolutePoint,
    RelativePoint,
    Mouse,
    MousePoint,
    Left,
    Top,
    Custom
}
getpointcomposition()
中,当
PlacementMode
相对
绝对点
相对点
MousePoint
时,它仅检查
MenuDropAlignment
。如果您可以使用另一种
放置模式
,则您将不会受到
菜单对齐
检查的约束

如果使用
PlacementMode.Custom
,则还需要将
Popup.CustomPopupPlacementCallback
设置为有效方法,以提供弹出窗口的
CustomPopupPlacement[]
坐标


来源:Reflector

这似乎是不可能的,因此我们在问题中使用MultiDataTrigger进行补偿。

我编写了一个自定义弹出窗口来解决这个问题:您可以设置ForceAlignment依赖项属性并使用“open”方法打开它,或者您可以直接调用“OpenLeft”和“OpenRight”方法

公共类自定义弹出窗口
继承原语。弹出窗口
私有共享moFI作为Reflection.FieldInfo=GetType(SystemParameters).GetField(“\u menuDropAlignment”,Reflection.BindingFlags.NonPublic+Reflection.BindingFlags.Static)
公共枚举对齐
无=0
左边
赖特
结束枚举
公共财产强制对齐作为强制对齐
得到
返回GetValue(ForceAlignmentProperty)
结束
设置(ByVal值作为对齐)
SetValue(ForceAlignmentProperty,值)
端集
端属性
公共共享只读ForceAlignmentProperty作为DependencyProperty=_
DependencyProperty.Register(“强制对齐”_
GetType(enuForceAlignment)、GetType(CustomPopup)_
新的FrameworkPropertyMetadata(enuForceAlignment.None))
公开分公开(
选择案例强制对齐
箱子,左对齐
OpenLeft()
病例对照,对吗
OpenRight()
其他情况
等参=真
结束选择
端接头
公共次公开权()
_打开(错误)
端接头
公共子OpenLeft()
_开放(真)
端接头
Private Sub_Open(paMenuDropAlignment为布尔值)
如果SystemParameters.MenuDropAlignment paMenuDropAlignment,则
moFI.SetValue(无,paMenuDropAlignment)
等参=真
moFI.SetValue(无,非paMenuDropAlignment)
其他的
等参=真
如果结束
端接头
末级

将整个应用程序设置为常规模式:

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

fi.SetValue(null, false);

这已经很老了,但如果你至少有.NET4.5,我找到了另一种方法

通过覆盖菜单项/弹出窗口模板,可以使用以下触发器:

<DataTrigger Binding="{Binding Path=(SystemParameters.MenuDropAlignment)}" Value="[True/False]">
    <Setter TargetName="Popup" Property="Placement" Value="[Left/Right]"/>
</DataTrigger>

当然,设置以下各项:

  • 您的datatrigger值为True或False
  • 左或右作为setter值

绑定使用binding Path=()语法而不是binding={x:static…}非常重要,这样您就可以使用静态类中的StaticPropertyChanged事件。

很抱歉这次延迟-但我刚刚检查了reflector,并且MenuDropAlignment用于枚举中除Center之外的所有项,而中心是不好的,因为它(据我所见)总是向下滑动而不是向上滑动。我认为这个答案没有得到足够的信任。其中有点隐藏,但如果这样做,基本上可以通过两行在系统范围内关闭它:FieldInfo fi=typeof(SystemParameters).GetField(“\u menuDropAlignment”,BindingFlags.NonPublic | BindingFlags.Static);fi.SetValue(null,false);这并不能在全系统范围内始终如一地发挥作用——它似乎会在短时间内产生效果,但会重新设置。在示例的上下文中,它可以正常工作-在打开之前设置-但不幸的是,您不能只设置一次。按照我之前的评论-您可以通过首先调用SystemParameters.MenuDropAlignment属性使设置“保持不变”-例如,如果在反射设置代码之前有“if(if(SystemParameters.MenuDropAlignment)”,设置的值将显示为s