【问题标题】:Why are my menus opening right to left instead of left to right?为什么我的菜单是从右到左而不是从左到右打开的?
【发布时间】:2016-09-16 12:43:12
【问题描述】:

我来自 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>

我错过了什么?

【问题讨论】:

  • 我能想到的只是你电脑上的文化可能会搞砸,试试在你的窗口中设置FlowDirection="LeftToRight"?此外,如果窗口位于屏幕的最右边缘,它将在另一侧弹出。
  • 我的文化是英文。 FlowDirection 似乎没有什么不同。我在&lt;Window&gt; 标签中添加了它,我认为这是正确的?它不在屏幕的最右侧,有足够的空间可以打开菜单。
  • 您的菜单中需要RenderTransform 吗?还是您使用设计器在屏幕上拖放东西?
  • 我使用设计器将项目拖到表单上。该属性是自动添加的,我不明白它的作用,所以我离开了它。删除它不会改变任何东西。
  • 对于投反对票的人,您能否发表评论,建议如何改进这篇文章。对我认为是明确的问题进行秘密投票是没有帮助的。

标签: wpf


【解决方案1】:

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

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>

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

【讨论】:

    【解决方案2】:

    我能够通过使用@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 构造函数调用这个函数。

    【讨论】:

      【解决方案3】:

      菜单的打开方式取决于SystemParameters.MenuDropAlignment 属性。如果您为惯用右手的人配置了平板电脑,这通常设置为向右对齐。

      可以在“控制面板”->“平板电脑设置”->“指定您用哪只手写笔”中更改计算机的设置。如果您的控制面板中没有平板电脑设置,您可以尝试运行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);
          }
      }
      

      【讨论】:

      • 很抱歉,我不太明白您的回答。我不在平板电脑上,这是标准台式电脑。在 WinForms 项目中的同一台 PC 上,菜单正确打开,仅在 WPF 中它们被反转。我确定我只是在某处遗漏了一个属性,不得不编写一个大规模的覆盖方法对我来说似乎有点矫枉过正,并没有解决实际原因。
      • @Equalsk 很容易识别。只需检查 SystemParameters.MenuDropAlignment 的值。如果为真,则弹出窗口配置为从右到左显示。在我的机器上,弹出窗口从右到左打开,在我应用this answer 的解决方案后,它们从左到右出现。所以这是实际原因(至少对我的机器而言)。
      • @Equalsk 您还可以检查控制面板-> 平板电脑设置-> 指定您使用(source answer) 书写的手。有两个选项“右手 - 菜单出现在您的手的左侧。”和“左撇子 - 菜单出现在您的右手边。”切换此单选按钮,按应用并查看应用中的更改。
      • 在连接第二台带内置触摸屏的显示器 (Dell P2418HT) 后,我在台式机 (Windows 10) 上遇到了同样的问题。我找到了您的代码的较短版本:red-gate.com/simple-talk/blogs/…
      猜你喜欢
      • 1970-01-01
      • 2016-05-02
      • 2013-06-21
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多