0

I have an WPF UserControl which is embedded within an elementhost so I can show it in a winforms application. I have a class that inherits from Form.This class contains the elementhost which in turn embeds the WPF control. I am trying to center this form within the parent window but without success. See below code I use (the class where I have this method is the Form).

When trying to get the handle of the parent window, I get a valid parentWindowHandle Id but parentWindow gets null (see below code).

Also within that method I have checked what is the value for base.StartPosition and it is FormStartPosition.CenterParent.

    private DialogResult ShowAsChild(bool showDialog = false)
    {
        NativeWindow parentWindow = null;
        try
        {
            IntPtr parentWindowHandle = Process.GetCurrentProcess().MainWindowHandle;
            parentWindow = NativeWindow.FromHandle(parentWindowHandle);
        }
        catch (Exception ex)
        {
            parentWindow = null;
        }
        
        if (parentWindow != null)
        {
            if (showDialog)
            {
                return base.ShowDialog(parentWindow);
            }
            else
            {
                base.Show(parentWindow);
            }
        }
        else
        {
            if (showDialog)
            {
                return base.ShowDialog();
            }
            else
            {
                base.Show();
            }
        }

        return DialogResult.None;
    }

I am calling the above method and showing the child window from the main UI thread and it is not working, child window is not centered within the parent. However, if I call the above method and show the child window from a timer, then it is centered correctly within the parent. The code executed in both cases is the same. The only difference is that one is executed from the main UI thread, and the other from a System.Windows.Forms.Timer, but in fact, when you execute code from a timer it also runs from the main UI thread, so I don't understand why it is hapenning.

Any ideas will be highly appreciated.

Willy
  • 9,848
  • 22
  • 141
  • 284
  • *I have a form that inherits from Form*: is there a reason why you feel the need to say this, what else could it be? -- It's not clear what calls this code, what *Parent Window* means and why you need to use `Process.GetCurrentProcess().MainWindowHandle` when you can pass the instance of the Form that shows this one. If this is the actual scenario. Or are you trying to *embed* this Form in another (setting `TopLevel = false`)? Something else? -- Can you show the calling code and give some more context to the operations? – Jimi Nov 24 '22 at 23:53
  • Note that a WPF Control is probably making the application DpiAware, if it's not already – Jimi Nov 24 '22 at 23:55
  • @Jimi Process.GetCurrentProcess().MainWindowHandle has sense because in fact the parent is the Outlook application. I have an Outlook VSTO Addin and from.the addin I show this window so I need to take the handle of Outlook window (parent) and show then that window as child centered on Outlook application. – Willy Nov 25 '22 at 07:52
  • You didn't mention that this is a VSTO Addin anywhere in your post, until now. See [here](https://stackoverflow.com/a/30666344/7444103) to get the handle of Outlook window -- As mentioned, when a WinForm application (or Window) that is not DpiAware uses WPF assemblies or is created within a WPF application (as Outlook), it becomes DpiAware, sometimes with *unexpected* timing. If you calculate the Forms measures before that point, you get *virtualized* values. Make sure your Addin is DpiAware from the start (you should probably update your .Net Framework version to at least 4.7.2) – Jimi Nov 25 '22 at 13:09

0 Answers0