Paul Michaels
Paul Michaels

Reputation: 16705

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?

Upvotes: 1

Views: 715

Answers (2)

Erti-Chris Eelmaa
Erti-Chris Eelmaa

Reputation: 26338

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".

Upvotes: 1

Mike Eason
Mike Eason

Reputation: 9723

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.

Upvotes: 0

Related Questions