WPF Office 加载项:如何设置对话框位置以显示在父项的中心 window

WPF Office Add-In: How to set a Dialog position to show at the center of the parent window

这是问题 here 的扩展。

我对代码进行了以下细微调整,以便在 Office 加载项的情况下工作。

Microsoft.Office.Interop.Outlook.Application app = Globals.ThisAddIn.Application;
if (app.ActiveWindow() != null)
{
   this.Left = app.ActiveWindow().Left + (app.ActiveWindow().Width - this.Width) / 2;
   this.Top = app.ActiveWindow().Top + (app.ActiveWindow().Height - this.Height) / 2;
}

这在正常情况下工作正常但在 HiDPI 条件下(例如在 Mac 高分辨率下)。弹出窗口 windows 显示在屏幕右下角。查看数字 app.ActiveWindow().Width 与其他值相比似乎很大。

我没能从@chessweb 得到好的 solution 来工作,因为调用 windows 是功能区中的一个按钮。

有什么想法吗?

我可以想到一些方法,但我可能会采用以下方法:

  1. 从活动 Outlook 获取句柄 Window。
  2. 在您的 Window 上设置父级。

要获取句柄,请使用:

using System.Runtime.InteropServices;

  //use pInvoke to find the window
  [DllImport("user32.dll", SetLastError = true)]
  static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  //now use it
  public static void Test(long handle)
  {
      Microsoft.Office.Interop.Outlook.Application app = Globals.ThisAddIn.Application;
      IntPtr hWnd = (IntPtr)FindWindow("rctrl_renwnd32[=10=]", app.ActiveWindow().Caption);

      TestingWindowView win = new TestingWindowView(hWnd);
      win.ShowDialog();
  }

然后,在你的 window 的构造函数中,你可以使用 WindowInteropHelper 来分配所有者:

using System.Windows.Interop;

    public TestingWindowView(IntPtr handle)
    {
        InitializeComponent();
        new WindowInteropHelper(this).Owner = handle;
    }

在 xaml 中,您现在可以这样做:

WindowStartupLocation="CenterOwner"

我确信还有其他方法可以获取 Outlook 的句柄,但这个方法已经过测试并且是正确的。

希望对您有所帮助

经过一些测试,我最终得到了以下效果很好的解决方案。

Microsoft.Office.Interop.Outlook.Application app = Globals.ThisAddIn.Application;
if (app.ActiveWindow() != null) {
  double WidthRatio = (1 / SystemParameters.FullPrimaryScreenWidth) * 
  System.Windows.Forms.Screen.FromHandle(new 
  WindowInteropHelper(this).Handle).Bounds.Width;
  double HeightRatio = (1 / SystemParameters.FullPrimaryScreenHeight) * 
  System.Windows.Forms.Screen.FromHandle(new 
  WindowInteropHelper(this).Handle).Bounds.Height;
  this.Left = (app.ActiveWindow().Left + (app.ActiveWindow().Width - this.Width * WidthRatio) / 2) / WidthRatio;
  this.Top = (app.ActiveWindow().Top + (app.ActiveWindow().Height - this.Height * HeightRatio) / 2) / HeightRatio;
}

注意:

  • 由于我无法解释的原因,身高比例不完美( 1.12 而不是 1 当没有缩放时 / 2.12 当使用缩放因子 2)
  • 假设高度和宽度比例因子相等, 只能使用一个,因此解决第一点

任何 comment/feedback 将不胜感激。