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 是功能区中的一个按钮。
有什么想法吗?
我可以想到一些方法,但我可能会采用以下方法:
- 从活动 Outlook 获取句柄 Window。
- 在您的 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 将不胜感激。
这是问题 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 是功能区中的一个按钮。
有什么想法吗?
我可以想到一些方法,但我可能会采用以下方法:
- 从活动 Outlook 获取句柄 Window。
- 在您的 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 将不胜感激。