【发布时间】:2015-09-23 14:22:26
【问题描述】:
我们在程序中遇到了应用程序菜单的问题,即应用程序菜单在一个意外的位置打开,具体取决于窗口所在的位置。
最初,应用程序菜单会直接在功能区应用程序菜单按钮的下方和左侧打开。我们实现了this question 中概述的解决方案,这导致应用程序菜单以我们想要的方向(向下和向右)打开。
不幸的是,有一个副作用。如上所述,当窗口位于显示器边缘附近时,应用程序菜单会在一个意想不到的位置打开,尽管具体情况因屏幕配置而异:
- 在单显示器系统上,当窗口与屏幕右边缘对齐时会出现这种情况。
- 在多显示器系统上,当窗口位于除最左侧之外的任何屏幕的左边缘 20 像素范围内时,就会发生这种情况。
在任何一种情况下,应用程序菜单都会在应用程序窗口的左侧打开,与窗口至少相隔 50 像素。
以下是展示上述行为的精简应用程序。
主窗口:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Custom="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
xmlns:Example="clr-namespace:Ribbon_Example"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
x:Class="Ribbon_Example.MainWindow"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Ribbon>
<Ribbon.ApplicationMenu>
<RibbonApplicationMenu>
<RibbonApplicationMenu.Resources>
<Example:NegativeIntegerConverter x:Key="NegativeIntegerConverter" />
<Style TargetType="Popup">
<Setter Property="Placement" Value="Left" />
<Setter Property="HorizontalOffset"
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=RibbonApplicationMenu},
Path=Width,
Converter={StaticResource ResourceKey=NegativeIntegerConverter}}" />
</Style>
</RibbonApplicationMenu.Resources>
<RibbonApplicationMenuItem Header="New..." />
<RibbonApplicationMenuItem Header="Open..." />
<RibbonApplicationMenuItem Header="Close" />
<RibbonApplicationMenuItem Header="Save" />
<RibbonApplicationMenuItem Header="Save As..." />
</RibbonApplicationMenu>
</Ribbon.ApplicationMenu>
</Ribbon>
</Grid>
</Window>
上述问题的类型转换器:
using System;
using System.Globalization;
using System.Windows.Data;
namespace Ribbon_Example
{
class NegativeIntegerConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
{
return -1 * System.Convert.ToInt32( value );
}
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
{
return -1 * System.Convert.ToInt32( value );
}
}
}
一张图片胜过千言万语,所以这里是这个问题的多显示器版本的一个例子。
我们可能做错了什么?
【问题讨论】: