Wpf 对话框实现失败,已经是另一个元素的逻辑子元素

Wpf 对话框实现失败,已经是另一个元素的逻辑子元素,wpf,mvvm,popup,Wpf,Mvvm,Popup,我试图在WPF+PRISM+MVVM应用程序中实现对话窗口。现在,我设法创建了示例服务,每个模块都可以使用此服务在窗口中显示任何视图,但问题是非常不寻常的,无法使其正常工作 这是窗口服务的合同 public interface IUiDialogueService : IDisposable { void Show<TView>(TView view) where TView : IViewModel; } public class UiDialogueService :

我试图在WPF+PRISM+MVVM应用程序中实现对话窗口。现在,我设法创建了示例服务,每个模块都可以使用此服务在窗口中显示任何视图,但问题是非常不寻常的,无法使其正常工作

这是窗口服务的合同

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;

    }
}

有人能解释一下这里出了什么问题吗?有没有更好的方法在MVVM architectur中获得子(对话)窗口?

尝试在
Show
的最后一行之前添加以下代码:

_dialogueWindow.Content = null;
Show
现在应该如下所示:

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;
}
public void Show(TView视图),其中TView:IViewModel
{
_dialogueWindow=新窗口
{
SizeToContent=SizeToContent.Width和Height,
ResizeMode=ResizeMode.NoResize,
ShowInTaskbar=false,
Content=view.view
};
_dialogueWindow.ShowDialog();
_dialogueWindow.Content=null;
_dialogueWindow=null;
}

WPF中的每个元素只能属于一个父元素。即使一个元素没有显示(或不再显示),父子关系仍然存在。如果要为元素指定一个新的父元素,则需要先将其从旧父元素中删除

在本例中,在
Show()
中,您将窗口的内容设置为您的视图。即使在显示该窗口之后,视图仍然是该窗口的子窗口。如果您现在尝试在不同的窗口中显示相同的视图,您将得到该异常


最好的方法是从窗口中删除视图(如Daniel Hilgarth的回答所述)。或者,您可以检查视图是否已经有父视图,然后首先手动将其从父视图中删除。

这似乎可行,但这是一个非常简单的实现,我想不出让此窗口在关闭事件时返回什么或调用回调函数。您能提供一些使用回调方法或对话结果选项实现此场景的好例子吗?由于代码引发了您的建议异常,我会将您的答案标记为已回答,但请提供有关回调的更多信息。@Rati\u Ge:我看不出回调与异常有什么关系。请创建一个关于回调的新问题-这对您更有利,因为您更有可能收到有用的答案。如有必要,您可以链接到此问题以了解上下文。
_dialogueWindow.Content = null;
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;
}