简体   繁体   中英

Positioning a dialog window in WPF

I have a command button that launches a separate window. I'm using the MVVM Cross architecture, and so the window is fed through a command in the ViewModel. The way that I've done this is a register a service in the UI layer that displays a window, and then in the command, to resolve that service and display the window:

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

    myService.ShowWindow();
}

Then, in the service (which is in the UI layer):

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();
    });
}        

The problem that I have is that I want to show the new dialog in a position relative to the position of the command button that launched it. Having done a bit of research, it looks like I need the FrameworkElement.PointToScreen() method, although what I can't determine is how to access this information without breaking the separation of concern.

Am I going about this the correct way, or is there an easier way? If i am, then how can I pas the framework element through the command?

You should have a method / command, as such:

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

    myService.ShowWindow(pos);
}

If that is done, you should use CommandParameter with Converter :

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

which basically can turn YourWindow into the correct WindowAbsoluteLocationPosition (user-defined) structure that is passed to your viewModel. Notice; you should also pass your button to the converter, in order to have better "reusability".

In this scenario, I would propose the following:

Create another method under the same name which has an additional parameter which represents the parent window:

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

You will need to also overload the ShowMyWindow method in the service with the same parameter to call this new ShowWindow method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM