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

发布于 2024-12-27 01:53:08 字数 1749 浏览 4 评论 0原文

我正在尝试在 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;

    }
}

这是我从模块访问窗口服务的方法。

    private void OnStartWizard()
    {
        _dialogueService.Show(ServiceLocator.Current
                    .GetInstance<IOrgManagementOrganizatioSetupViewViewModel>());
    }

当我第一次打开窗口时一切正常,但在我关闭它并在窗口内打开相同或其他视图后,我恢复了以下异常

指定的元素已经是另一个元素的逻辑子元素。先断开连接。

以下代码引发此异常。

        _dialogueWindow = new Window
                              {
                                  SizeToContent = SizeToContent.WidthAndHeight,
                                  ResizeMode = ResizeMode.NoResize,
                                  ShowInTaskbar = false,
                                  Content = view.View
                              };

谁能解释一下这里出了什么问题,并且有没有更好的方法在 MVVM 架构中获取子(对话)窗口?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雾里花 2025-01-03 01:53:09

WPF 中的每个元素只能属于一个父元素。即使某个元素不再显示(或不再显示),父子关系仍然存在。如果你想给一个元素一个新的父元素,你需要先将它从旧的父元素中删除。

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

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

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.

南汐寒笙箫 2025-01-03 01:53:08

尝试在 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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文