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

4
我们的程序中的应用程序菜单存在问题,具体表现为应用程序菜单在打开时出现在意料之外的位置,这与窗口所在的位置有关。
最初,应用程序菜单会直接在功能区的应用程序菜单按钮下方和左侧打开。我们实施了此问题中概述的解决方案,使应用程序菜单朝我们想要的方向打开(向下和向右)。
不幸的是,这带来了一个副作用。如上所述,当窗口靠近监视器边缘时,应用程序菜单将在意料之外的位置打开,尽管具体情况因屏幕配置而异:
  • 在单显示器系统上,当窗口与屏幕的右侧对齐时会发生这种情况。
  • 在多显示器系统上,当窗口距除最左侧以外的任何屏幕的左侧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

更新 这是我的看法:

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>

我已经解决了你所展示的问题。我也在使用双显示器电脑。


1
不幸的是,这个更改导致应用程序菜单在正常情况下(靠近屏幕中心点时)向左打开(超出窗口框架)。当在屏幕左边缘时,应用程序菜单仍将打开到窗口的左侧,但与该屏幕边缘左对齐。这是我们遇到的原始行为。你看到的效果如何? - Amelamise
@Amelamise 你能测试一下添加 <Setter Property="FlowDirection" Value="LeftToRight"/> 是否有所帮助吗? - netaholic
这真是奇怪。看了你们两个的屏幕截图,我们的代码和引用都是一模一样的,但行为完全不同。 - Amelamise
我刚试了一下FlowDirection属性 - 我认为那指的是语言的流向,而不是菜单的。无论哪种情况,菜单仍然向左打开。 - Amelamise
@Amelamise,实际上这种错误行为是正确的。当您将Placement设置为Left时,如果有足够的空间,弹出窗口将尝试出现在父控件的左侧。转换器并不会修复它,它只是将弹出窗口的x坐标移动到父控件的宽度。通过将Placement设置为BottomRelativeRight,您的弹出窗口应该可以正常工作。您能否检查一下是否如此? - netaholic
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接