none
InvalidOperationException - Bei dem angegebenen Element handelt es sich bereits um das logische untergeordnete Element eines anderen Elements. Führen Sie zuerst eine Trennung durch. RRS feed

  • Frage

  • Hallo liebe Community,

    ich entwickle momentan ein Programm, bei dem an einer Stelle Bilder (in meinem Fall Image-Objekte) aus einer ObservableCollection<Image> in ViewBox-Objekte gepackt werden sollen. Diese wiederum sollen in ein Grid geschrieben werden. Dazu habe ich folgenden Code geschrieben:

    ObservableCollection<Image> bilder = new ObservableCollection<Image>();
    Grid bilderGrid = new Grid();
    
    ...
    
    void bilder_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
            {
                //Alle aktuell existierenden Spalten, Zeilen und die Elemente der Tabelle entfernen
                BilderGrid.ColumnDefinitions.Clear();
                BilderGrid.RowDefinitions.Clear();
                BilderGrid.Children.Clear();
    
                //Anzahl der Zeilen und Spalten aus der Anzahl
                //der Elemente der Auflistung "bilder" errechnen
                int anzahlZeilen = Convert.ToInt32(Math.Ceiling(Math.Sqrt(bilder.Count)));
                int anzahlSpalten = Convert.ToInt32(Math.Round(Convert.ToDouble(bilder.Count)));
    
                //Spalten und Zeilen hinzufügen
                for (int i = 0; i < anzahlZeilen; i++)
                {
                    BilderGrid.RowDefinitions.Add(new RowDefinition());
                }
                for (int i = 0; i < anzahlSpalten; i++)
                {
                    BilderGrid.ColumnDefinitions.Add(new ColumnDefinition());
                }
    
                
                //Elemente erzeugen und an passender Stelle einfügen
                for (int i = 0; i < bilder.Count; i++)
                {
                    Viewbox view = null;
                    view = new Viewbox();
                    view.Stretch = Stretch.Uniform;
                    view.SetValue(Grid.RowProperty, Convert.ToInt32(Math.Ceiling(Math.Sqrt(i))));
                    view.SetValue(Grid.ColumnProperty, Convert.ToInt32(Math.Round(Convert.ToDouble(i))));
    
                    view.Child = bilder[i]; //Hier tritt die InvalidOperationException auf
    
                    BilderGrid.Children.Add(view);
                }
            }

    Wie im Code kommentiert, tritt die bei der Zuweisung

    view.Child = bilder[i];

    eine InvalidOperationException auf. Wenn ich der "Child"-Property den Wert "null" zuweise, tritt die Exception nicht mehr auf, es muss also an der Auflistung liegen. Als nähere Information zur Exception sagt mir VS folgendes:

    "Bei dem angegebenen Element handelt es sich bereits um das logische untergeordnete Element eines anderen Elements. Führen Sie zuerst eine Trennung durch."

    Weiß jemand, wo hier der Fehler liegt?

    Vielen Dank im Vorraus,

    Julian

    Sonntag, 9. Februar 2014 15:57

Antworten

  • Es geht hier um den LogicalTree und nicht um den VisualTree. Diese unterscheiden sich in den meisten Fällen. Nun habe ich mal ein wenig getestet und habe gemerkt, das das Parent noch die ViewBox vom letzten hinzufügen war. Entferne diese also zunächst und füge das Bild erst danach wieder ein.

    if (bilder[i].Parent is Viewbox)
        (bilder[i].Parent as Viewbox).Child = null;//ViewBox entfernen

    Dann sollte es laufen.

    PS: Wenn du merkst, dass das Parent bereits eine Viewbox ist, kannst du es dir natürlich sparen eine neue um das Bild herum zu packen. Statt dessen kannst du diese gleich wieder hinzufügen:

    if(bilder[i].Parent is Viewbox)
    {
      grid.Children.Add(bilder[i].Parent);
    }
    else{
    //Neue Viewbox erstellen und Bild verpacken
    }


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.


    Sonntag, 9. Februar 2014 18:02
    Moderator

Alle Antworten

  • Hallo,
    wenn du ein Control verschieben willst, darf es in keinem anderen mehr enthalten sein. Irgendwo ist bilder[i] also noch das Kind eines anderen Elements.

    Angenommen ein Grid enthält noch das Bild, dann entferne es einfach aus der Auflistung und verschiebe es danach in die ViewBox:

    grid.Children.Remove(bilder[i]);//Bild aus Auflistung entfernen
    view.Child = bilder[i];//In ViewBox packen
    Bei einem Border (o.ä.) müsstest du lediglich der Child-Eigenschaft null zuweisen.


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    Sonntag, 9. Februar 2014 16:06
    Moderator
  • Vielen Dank für die Antwort, leider hat sie mich nicht weitergebracht. Ich habe jetzt mittels

    VisualTreeHelper.GetParent(bilder[i]);

    auf Eltern geprüft, jedoch kam immer der Wert "null" zurück, das Bild hat also anscheinend keine Eltern mehr.

    Sonntag, 9. Februar 2014 17:50
  • Es geht hier um den LogicalTree und nicht um den VisualTree. Diese unterscheiden sich in den meisten Fällen. Nun habe ich mal ein wenig getestet und habe gemerkt, das das Parent noch die ViewBox vom letzten hinzufügen war. Entferne diese also zunächst und füge das Bild erst danach wieder ein.

    if (bilder[i].Parent is Viewbox)
        (bilder[i].Parent as Viewbox).Child = null;//ViewBox entfernen

    Dann sollte es laufen.

    PS: Wenn du merkst, dass das Parent bereits eine Viewbox ist, kannst du es dir natürlich sparen eine neue um das Bild herum zu packen. Statt dessen kannst du diese gleich wieder hinzufügen:

    if(bilder[i].Parent is Viewbox)
    {
      grid.Children.Add(bilder[i].Parent);
    }
    else{
    //Neue Viewbox erstellen und Bild verpacken
    }


    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.


    Sonntag, 9. Februar 2014 18:02
    Moderator
  • Vielen Dank, das hat geholfen. Komisch ist allerdings, dass auch mit dem LogicalTree und der Eigenschaft "Parent" immer null zurückgegeben wird, aber was solls.

    Viele Grüße und nochmals Danke!

    Sonntag, 9. Februar 2014 19:54
  • Ja, genau das ist das Problem. Bevor ein Element hinzugefügt wird (bei mir passierte das bei OnApplyTemplate), muss geprüft werden, es über einen Parent verfügt, was bedeutet, dass es bereits hinzugefügt worden sein muss. In dem Falle kann man je nach Bedarf entsprechend darauf reagieren

    Freitag, 17. März 2017 12:47