为什么我的菜单是从右到左而不是从左到右打开?

问题描述 投票:0回答:4

我来自 WinForms,第一次自学 WPF。
我想我应该首先在 WPF 中重新创建我的一个 WinForms 应用程序的界面,但我已经遇到了菜单问题。

我不明白为什么 WPF 应用程序中的菜单从右到左打开,而 WinForms 应用程序上的菜单从左到右打开(这就是我想要的):

这实际上是一个空项目,只有默认设置。这是 XAML:

<Window x:Class="WpfTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test" Height="541.771" Width="828.947" WindowStartupLocation="CenterScreen">
    <DockPanel LastChildFill="False" Margin="0" Background="#FFFDFD9C">
        <Menu x:Name="menu" Height="22" VerticalAlignment="Top" RenderTransformOrigin="1.79,0.076" DockPanel.Dock="Top" Margin="0">
            <MenuItem Header="File">
                <MenuItem Header="New Document"/>
                <MenuItem Header="Open Template"/>
                <MenuItem Header="Open Collateral"/>
                <Separator/>
                <MenuItem Header="Synchronise"/>
                <Separator/>
                <MenuItem Header="Build Document"/>
                <MenuItem Header="Document History">
                    <MenuItem Header="Load Last Document"/>
                </MenuItem>
                <Separator/>
                <MenuItem Header="Settings"/>
                <Separator/>
                <MenuItem Header="Exit"/>
            </MenuItem>
            <MenuItem Header="Help">
                <MenuItem Header="User Guide"/>
                <MenuItem Header="About"/>
            </MenuItem>
        </Menu>
        <Rectangle Fill="#FFB8B8FF" Height="80" VerticalAlignment="Top" DockPanel.Dock="Top" Margin="0"/>
    </DockPanel>
</Window>

我错过了什么?

wpf
4个回答
13
投票

菜单的打开方式取决于

SystemParameters.MenuDropAlignment
属性。如果您的平板电脑是为惯用右手的人配置的,则通常将其设置为向右对齐。

可以在“控制面板”->“平板电脑设置”->“指定用哪只手书写”中更改计算机的设置。如果您的控制面板中没有 Tablet PC 设置,您可以尝试运行

shell:::{80F3F1D5-FECA-45F3-BC32-752C152E456E}
。这应该会打开 Tablet PC 设置配置对话框(来源:https://stackoverflow.com/a/25109673/3506292)。您还可以创建一个注册表项来更改此设置。

如果绝对需要,您可以使用 thisthat 问题的答案来覆盖此行为。

最简单的更改(来自https://stackoverflow.com/a/22065976/3506292

private static readonly FieldInfo _menuDropAlignmentField;
static MainWindow()
{
    _menuDropAlignmentField = typeof(SystemParameters).GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);
    System.Diagnostics.Debug.Assert(_menuDropAlignmentField != null);

    EnsureStandardPopupAlignment();
    SystemParameters.StaticPropertyChanged += SystemParameters_StaticPropertyChanged;
}

private static void SystemParameters_StaticPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    EnsureStandardPopupAlignment();
}

private static void EnsureStandardPopupAlignment()
{
    if (SystemParameters.MenuDropAlignment && _menuDropAlignmentField != null)
    {
        _menuDropAlignmentField.SetValue(null, false);
    }
}

3
投票

我能够通过使用 @SLA80 的 link 中的代码来实现修复,他们对上面批准的答案的评论中。

在 App.xaml.cs 中,我添加了以下代码:

private static void SetDropDownMenuToBeRightAligned()
    {
        var menuDropAlignmentField = typeof(SystemParameters).GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);
        Action setAlignmentValue = () =>
        {
            if (SystemParameters.MenuDropAlignment && menuDropAlignmentField != null) menuDropAlignmentField.SetValue(null, false);
        };

        setAlignmentValue();

        SystemParameters.StaticPropertyChanged += (sender, e) =>
        {
            setAlignmentValue();
        };
    }

我从 App 构造函数中调用此函数。


2
投票

这个节目很晚了,但尽管如此,这是我的解决办法。 当然,更改注册表项可以解决问题:

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows

改变

REG_SZ: MenuDropAlignment

按照您的意愿。值 0 表示右,1 表示左。

但是,如果您的布局看起来很糟糕,您不能假设用户会查找并发现此问题。 修复方法是在 MenuItem 样式中应用 Datatrigger。 在“TopLevelHeaderTemplate”中查找“PART_Popup”,例如

 <Popup
    x:Name="PART_Popup"
    AllowsTransparency="true"
    Focusable="false"
    IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}"
    Placement="Bottom"
    PlacementTarget="{Binding ElementName=templateRoot}"
    PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
    >

并应用 DataTrigger:

 <DataTrigger Binding="{Binding Source={x:Static SystemParameters.MenuDropAlignment}}" Value="True">
     <Setter TargetName="PART_Popup" Property="Placement" Value="Left" />
     <Setter TargetName="PART_Popup" Property="HorizontalOffset" Value="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource NegativeConverter}}" />
     <Setter TargetName="PART_Popup" Property="VerticalOffset" Value="{Binding ElementName=templateRoot, Path=ActualHeight}" />
 </DataTrigger>

这对我有用,因为更改注册表项会产生相同的结果。


0
投票

组合:

  • Windows 认为您的电脑具有笔/触摸输入(又称平板电脑)
  • WinForms 默认情况下不遵循 Windows Tablet PC 惯用手设置
  • 您电脑上的惯用手设置被设置为右手(菜单在您的手/鼠标左侧打开)

如果您想覆盖应用程序中的设置,请按照其他答案操作;否则,保持原样。

您可能想调查为什么您的 Windows 认为您有笔/触摸输入。

© www.soinside.com 2019 - 2024. All rights reserved.