Question

J'ai une solution PRISM / WPF / MEF qui contient un avalondock. J'ai créé un RegionAdapterBase<Pane> classe qui gère la création et le retrait des vitesses d'Avalondock.

Voici le problème que je rencontre:

  1. Je clique sur un bouton dans mon menu et une vue est enregistrée avec une région et affichée dans mon DocumentPane
  2. Je clique sur le bouton Fermer dans Avalondock pour fermer l'onglet et supprimer la vue
  3. Je clique sur le même bouton de menu pour l'ajouter
  4. Je reçois l'erreur:

"L'élément spécifié est déjà l'enfant logique d'un autre élément. Débranchez-le d'abord."

Donc ... cela me dit que quelque chose persiste que je dois supprimer, mais je ne peux pas comprendre où il se trouve. Voici un peu de code de ma région ADAPTER:

private void OnViewsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e, IRegion region, Pane regionTarget)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        foreach (object item in e.NewItems)
        {
            UIElement view = item as UIElement;

            if (view is ITabViewInfo)
            {
                if (view != null)
                {
                    DockableContent newContentPane = new DockableContent()
                    {
                        Content = item,
                        Title = ((ITabViewInfo)view).TabViewTitle,
                        Icon = new Image()
                        {
                            Source = new BitmapImage(((ITabViewInfo)view).TabViewIcon)
                        }.Source,
                        IsCloseable = ((ITabViewInfo)view).IsCloseable,
                        HideOnClose = ((ITabViewInfo)view).IsHideOnClose
                    };

                    newContentPane.Closed += (contentPaneSender, args) =>
                    {
                        Debug.WriteLine("Removing view from region", "Prism");
                        region.Remove(item);
                    };

                    regionTarget.Items.Add(newContentPane);
                    newContentPane.Activate();
                }
            }
        }
    } else if (e.Action == NotifyCollectionChangedAction.Remove) {
            regionTarget.Items.Clear();
    }
   }

De mes lignes de débogage, le DocumentPane et les vues de région sont correctement détruites ... lorsque je clique pour ajouter l'élément à la vue, j'obtiens le message d'erreur ci-dessus sur la ligne qui fait:

Content = item,

Voici le code de mon module qui s'exécute lorsque le bouton de menu est enfoncé:

    if (_regionManager.Regions["MainRegion"].Views.Any(m => m.GetType() == typeof(Views.ClassicFrontierView)))
    {
        Debug.WriteLine(_regionManager.Regions["MainRegion"].Views.Count());
    }
    else
    {
        Debug.WriteLine("Adding view to region", "Prism");
        _regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.ClassicFrontierView));
    }

Une idée de ce qui me manque?

Était-ce utile?

La solution 2

Au lieu de gérer l'événement fermé (qui peut avoir perdu une référence à la vue sous-jacente), je gère l'événement de clôture.

Cela a cependant fonctionné lorsque j'ai essayé de rouvrir l'onglet, il affichait la même instance. Après avoir lu ceci Dans le WPF composite (prisme), quelle est la différence entre iregion.add et iregionManager.RegisterViewWithRegion? J'ai changé ceci:

_regionManager.RegisterViewWithRegion("MainRegion", typeof(Views.ClassicFrontierView));

pour ça:

_regionManager.Regions["MainRegion"].Add(new Classic.Views.ClassicFrontierView());

Je dois encore faire des recherches avec Prism / Avalondock pour m'assurer qu'il n'y aura pas de fuites de mémoire, mais pour l'instant, cela semble fonctionner.

Autres conseils

Créez-vous une nouvelle vue à chaque fois ou que vous essayez d'afficher la vue existante plusieurs fois? Si le second est correct, j'essaierais ceci:

else if (e.Action == NotifyCollectionChangedAction.Remove) {
    foreach (DockableContent content in regionTarget.Items)
        content.Content = null;
    regionTarget.Items.Clear();
}

Vous devez probablement le retirer de regionTarget aussi bien.

Vous pouvez utiliser Snoop pour voir ce qui n'a pas été supprimé de l'arborescence visuelle, puis essayer de trouver le conteneur dont vous avez besoin pour supprimer votre élément. D'autres possibilités sont des choses comme une image d'icône non congelée, etc.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top