Wpf 对话框实现失败,已经是另一个元素的逻辑子元素
我试图在WPF+PRISM+MVVM应用程序中实现对话窗口。现在,我设法创建了示例服务,每个模块都可以使用此服务在窗口中显示任何视图,但问题是非常不寻常的,无法使其正常工作 这是窗口服务的合同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 :
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;
}