如何防止功能区的应用程序菜单在窗口外打开?

时间:2015-09-23 14:22:26

标签: c# wpf ribbon

我们的程序中的应用程序菜单遇到了问题,应用程序菜单在意外的位置打开,具体取决于窗口的位置。

最初,应用程序菜单将直接在功能区的应用程序菜单按钮的左下方打开。我们实现了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 );
        }
    }
}

一张价值千言万语的图片,所以这里是这个问题的多显示器版本的一个例子。

multi-monitor problem example

我们可能做错了什么?

1 个答案:

答案 0 :(得分:0)

<强>更新 以下是我的看法:

enter image description here

enter image description here

我已经运行了你的代码而只是改变了你的代码

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

  <Style TargetType="Popup">
        <Setter Property="Placement" Value="Relative" />
  </Style>

为我确定了你所展示的行为。我也在使用双监视器PC