在 WPF 中定位对话框窗口

本文关键字:对话框 窗口 定位 WPF | 更新日期: 2023-09-27 18:34:30

我有一个命令按钮,可以启动一个单独的窗口。 我使用的是 MVVM Cross 架构,因此窗口是通过 ViewModel 中的命令馈送的。 我这样做的方法是在显示窗口的 UI 层中注册一个服务,然后在命令中解析该服务并显示窗口:

public static void ShowMyWindow()
{
    IShowMyWindowService myService = Mvx.Resolve<IShowMyWindowService>();        
    myService.ShowWindow();
}

然后,在服务(在 UI 层中(:

public void ShowWindow()
{
    Window myWindow = new Window();
    myWindow.Content = new MyUserControl();
    Application.Current.Dispatcher.Invoke(() =>
    {
        myWindow.Owner = Application.Current.MainWindow;
        // Need to set x, y to the position of the button that invoked the command
        myWindow.Left = x;
        myWindow.Top = y;
        myWindow.ShowDialog();
    });
}        

我遇到的问题是我想在相对于启动它的命令按钮的位置显示新对话框。 做了一些研究后,看起来我需要FrameworkElement.PointToScreen()方法,尽管我无法确定如何在不破坏关注点分离的情况下访问这些信息。

我这样做是正确的,还是有更简单的方法? 如果是,那么我如何通过命令填充框架元素?

在 WPF 中定位对话框窗口

你应该有一个方法/命令,如下所示:

public static void ShowMyWindow(WindowAbsoluteLocationPosition pos)
{
    IShowMyWindowService myService = Mvx.Resolve<IShowMyWindowService>();        
    myService.ShowWindow(pos);
}

如果这样做,您应该将CommandParameterConverter一起使用:

<Button Command="{Binding YourCommand}" 
        CommandParameter="{Binding ElementName=YourWindow, 
            Converter={StaticResource yourConverter}}" />

这基本上可以将YourWindow转换为传递给视图模型的正确WindowAbsoluteLocationPosition(用户定义(结构。通知;您还应该将按钮传递给转换器,以获得更好的"可重用性"。

在这种情况下,我会提出以下建议:

创建另一个同名方法,该方法具有表示父窗口的附加参数:

public void ShowWindow(Window parentWindow)
{
   //Access the parentWindow location properties to work out a relative position to show the dialog
}

您还需要使用相同的参数重载服务中的 ShowMyWindow 方法,才能调用此新的 ShowWindow 方法。