4

I have two WPF application and one process manager that pass data from first WPF application to second WPF application and vice-versa. In one use case I have to show the window(main window) of the first application over the window(main window) of the second application in modal mode. So the window of the second WPF application will be disabled and on top of that window from first WPF application will be shown. Required behavior is same as showing a window in modal mode in a single WPF application. Any idea how can I access the Window of one WPF application from another WPF application??

In the case of Winform application we have done it by passing the Window Handle(intPtr) to another application and while showing the window in modal mode use the handle like:

System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window)

How similar thing can be achieved in the case of WPF application? Thanks in advance.

Kamal Kr
  • 687
  • 1
  • 10
  • 22

2 Answers2

4

=========================== BEGIN UPDATE =====================================

Code:

using System.Windows; // Window, WindowStartupLocation
using System.Windows.Interop; // WindowInteropHelper
using System.Runtime.InteropServices; // DllImport
...

// Instantiate the owned WPF window
CenteredWindow cw = new CenteredWindow();
// Get the handle to the non-WPF owner window
IntPtr hWnd = ...

CenteredWindow cw = new CenteredWindow();

EnableWindow(hWnd, false); // disable parent window
try
{
    // Set the owned WPF window’s owner with the non-WPF owner window
    WindowInteropHelper helper = new WindowInteropHelper(cw);
    helper.Owner = hWnd;
    cw.ShowDialog();
}
finally
{
    EnableWindow(hWnd, true); // enable parent window
}

...
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool EnableWindow(IntPtr hwnd, bool enable);

With the help of the MS Connect Link in @kamal-nayan 's comments, I modified my code as above, it works well for me.

The key is to disable the parent window, and when your modal dialog is closed, enable the parent window.

=========================== END UPDATE =====================================

using System.Windows; // Window, WindowStartupLocation
using System.Windows.Interop; // WindowInteropHelper
...
// Instantiate the owned WPF window
CenteredWindow cw = new CenteredWindow();

// Get the handle to the non-WPF owner window
IntPtr ownerWindowHandle = ...; // Get hWnd for non-WPF window

// Set the owned WPF window’s owner with the non-WPF owner window
WindowInteropHelper helper = new WindowInteropHelper(cw);
helper.Owner = ownerWindowHandle;
cw.ShowDialog();

This is the only solution I found. It's not real Modal, i.e. you could still activate the parent, but the good thing is that the child window is still on top of the parent.

http://blogs.msdn.com/b/wpfsdk/archive/2007/04/03/centering-wpf-windows-with-wpf-and-non-wpf-owner-windows.aspx

terry
  • 1,569
  • 11
  • 19
  • this is not what I wanted. I had tried this but it does not work like real modal. I will add the code that I am currently using to achieve this. – Kamal Kr Mar 27 '14 at 06:12
  • I am spending some more time on this to see if it works or not. I will try this one more time. This link has more. it disables the parent window after opening the modal mode and then again enables it. it might be helpful. https://connect.microsoft.com/VisualStudio/feedback/details/725866/when-i-host-a-wpf-control-from-one-process-to-another-process-i-cant-show-modal-dialog – Kamal Kr Mar 28 '14 at 06:51
0
_parameters = new HwndSourceParameters("myWindow");

_parameters.WindowStyle = WindowStyles.WS_SYSMENU | WindowStyles.WS_VISIBLE | WindowStyles.WS_CAPTION | WindowStyles.WS_CHILD | WindowStyles.WS_POPUP;
_parameters.SetPosition(50, 50);

_parameters.ParentWindow = ParentWindowHandle;           
_hwndSource = new HwndSource(_parameters);

_hwndSource.SizeToContent = SizeToContent.WidthAndHeight;
_hwndSource.RootVisual = modalWindowContent;

This is how I was able to show the window from one process as modal to window from other process.

terry
  • 1,569
  • 11
  • 19
Kamal Kr
  • 687
  • 1
  • 10
  • 22
  • Thanks, I modified your code a little, because the constructors of HwndSourceParameters, requires a string parameter. – terry Mar 28 '14 at 06:09
  • it doesn't work for me, maybe I missed any thing. Will look into it again. – terry Mar 28 '14 at 06:19
  • yes it might not work. it is not straight, particularly assigning the root visual. it needs the content. it does not accept the window. it requires a lot of workaround. I am also trying remove this piece of code. – Kamal Kr Mar 28 '14 at 06:48
  • Update, in my test vm, your code using HwndSourceParameters works the same as mine one using WindowInteropHelper. I guess I may need to set some window style or ex style, not sure. Since winform one works, so it's technically possible. Another possible solution is using a ElementHost in WinForm hosting a WPF user control. – terry Mar 28 '14 at 13:32
  • Your ms connect link is helpful, I've updated my code, and it works for me now, see my update. – terry Mar 29 '14 at 10:43