简体   繁体   中英

InvalidOperationException raised when navigating back to a view

I've a child view (SharedView) that's shared between two parent views so I add it to each parent view through a Region like this

<StackPanel>
  <ContentControl cal:RegionManager.RegionName="SharedViewRegion" />
</StackPanel>

In the parent view's ViewModel I register the child view like this

regionManager.RegisterViewWithRegion("SharedViewRegion", typeof(SharedView));

When I run the application if I open only one of the parent views it works as expected but if I open the two parent views then I get the following exception

An exception occurred while creating a region with name 'SecondRegion'. The exception was: System.InvalidOperationException: Specified element is already the logical child of another element. Disconnect it first.

I've been googling and this is the closer solution I found to my problem InvalidOperationException occurs when the same view instance is added to multiple ContentControl regions

But I'm using the prism navigation feature so I'm instancing the parent view like this

regionManager.RequestNavigate("ModuleRegion", new Uri("ParentView1", UriKind.Relative));

Can someone help me to solve this?

Try doing the following:

Add a name to the ContentControl that is hosting the region

Now you have to remove the region's content before leaving the parent view so in the ViewModel add the following code to the OnNavigatedFrom method

public void OnNavigatedFrom(NavigationContext navigationContext)
{
  ParentView.MyContentControl.Content = null;
}

Note: You can access the parent view importing it in your ViewModel.

Now you need to add the content to the region by hand because you removed it before leaving the region. Here's the code

public void OnNavigatedTo(NavigationContext navigationContext)
{
  SharedView view = (SharedView)ServiceLocator.Current.GetInstance(typeof(SharedView));
  ParentView.MyContentControl.Content = view;
}

Note: In this method you must add some workaround because the first time you open this view you'll get a System.InvalidOperationException because PRISM will try to add the SharedView to MyContentControl.

Here's a possible workaround

bool isFirstTime = true;

public void OnNavigatedTo(NavigationContext navigationContext)
{
  if (isFirstTime)
  {
    isFirstTime = false;
    return;
  }
  SharedView view = (SharedView)ServiceLocator.Current.GetInstance(typeof(SharedView));
  ParentView.MyContentControl.Content = view;
}

You have to do the same work in all parent views that share the SharedView

I hope this help you

You should directly add view to region instead of view discovery for this case. Give unique names to your parent views (you can use a counter to make up a unique name).

var region = this.regionManager.Regions["SharedViewRegion"];
var viewName = string.Format("SharedView{0}", this.countParent+1);

//Only add if it doesn't exist
var view = region.GetView(viewName);
if (null==view)
{
 //Use container to get new instance of the parent view.
 view = this.container.Resolve<SharedView>();
 region.Add(view, name);
 //Increment the counter as you added a new parent view 
 this.countParent++;
}

//Now activate the view
region.Activate(view);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM