Reputation: 1270
I am trying to implement dialogue window in WPF + PRISM + MVVM application. for now I managed to create sample service and each module is able to use this service to show any view in window, but the problem is something very unusual and can not make it work.
Here is the contract of the window service.
public interface IUiDialogueService : IDisposable
{
void Show<TView>(TView view) where TView : IViewModel;
}
public class UiDialogueService : IUiDialogueService, IDisposable
{
private Window _dialogueWindow;
#region Implementation of IUiDialogueService
public void Show<TView>(TView view) where TView : IViewModel
{
_dialogueWindow = new Window
{
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.NoResize,
ShowInTaskbar = false,
Content = view.View
};
_dialogueWindow.ShowDialog();
_dialogueWindow = null;
}
}
Here is how I access my window service from module.
private void OnStartWizard()
{
_dialogueService.Show(ServiceLocator.Current
.GetInstance<IOrgManagementOrganizatioSetupViewViewModel>());
}
everything works well when I first open window but after I close it and open same or other view inside window I revive following exception
Specified element is already the logical child of another element. Disconnect it first.
this exception is thrown by following code.
_dialogueWindow = new Window
{
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.NoResize,
ShowInTaskbar = false,
Content = view.View
};
Could anyone explain what is going on wrong here and Is there any better way to get child(dialogue) window in MVVM architectur?
Upvotes: 3
Views: 632
Reputation: 17638
Each element in WPF can only belong to one parent element. Even if an element is not shown (or shown anymore), the parent-child relationship remains. If you want to give an element a new parent you need to remove it first from the old parent.
In your case, in Show()
you are setting the Content of the window to your view. Even after that window was shown, the view still is the child of that window. If you now try to show that same view in a different window, you'll get that exception.
The best way is to remove the view from the Window (described in Daniel Hilgarth's answer). Alternatively, you could check if the view already has a Parent, and manually remove it from that parent first.
Upvotes: 1
Reputation: 174299
Try adding the following code before the last line of Show
:
_dialogueWindow.Content = null;
Show
should now look like this:
public void Show<TView>(TView view) where TView : IViewModel
{
_dialogueWindow = new Window
{
SizeToContent = SizeToContent.WidthAndHeight,
ResizeMode = ResizeMode.NoResize,
ShowInTaskbar = false,
Content = view.View
};
_dialogueWindow.ShowDialog();
_dialogueWindow.Content = null;
_dialogueWindow = null;
}
Upvotes: 3