我来自 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>
我错过了什么?
SystemParameters.MenuDropAlignment
属性。如果您的平板电脑是为惯用右手的人配置的,则通常将其设置为向右对齐。
可以在“控制面板”->“平板电脑设置”->“指定用哪只手书写”中更改计算机的设置。如果您的控制面板中没有 Tablet PC 设置,您可以尝试运行
shell:::{80F3F1D5-FECA-45F3-BC32-752C152E456E}
。这应该会打开 Tablet PC 设置配置对话框(来源:https://stackoverflow.com/a/25109673/3506292)。您还可以创建一个注册表项来更改此设置。
如果绝对需要,您可以使用 this 或 that 问题的答案来覆盖此行为。
最简单的更改(来自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);
}
}
我能够通过使用 @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 构造函数中调用此函数。
这个节目很晚了,但尽管如此,这是我的解决办法。 当然,更改注册表项可以解决问题:
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>
这对我有用,因为更改注册表项会产生相同的结果。
组合:
如果您想覆盖应用程序中的设置,请按照其他答案操作;否则,保持原样。
您可能想调查为什么您的 Windows 认为您有笔/触摸输入。