Laden...

MenuItem, das in zwei ContextMenus verwendet wird, "verschwindet"

Erstellt von Palladin007 vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.568 Views
Palladin007 Themenstarter:in
2.080 Beiträge seit 2012
vor 8 Jahren
MenuItem, das in zwei ContextMenus verwendet wird, "verschwindet"

Hi,

ich habe zwei ContextMenus, die an unterschiedlichen Stellen genutzt werden.
Eines davon erhält seine Elemente durch eine CompositeCollection, die unter Anderem einen CollectionContainer enthält, der die MenuItems beinhaltet, um die es geht.
Das andere ContextMenu enthält ein MenuItems, dessen Items wiederum aus dem selben CollectionContainer kommen.

Diese MenuItems existieren somit an zwei Stellen, wenn ich sie nun an beiden Stellen zwei, drei mal nutze, dann "verschwinden" sie an einer Stelle.
Das ContextMenu ist immer noch da und der Platz für die MenuItems auch, aber die MenuItems selber nicht mehr.

Ich habe das gleiche Verhalten auch reproduzieren können, wenn ich in den Resourcen ein MenuItem ablege, welches ich an zwei Stellen nutze. Klicke ich zwei, drei mal in den beiden ContextMenus die MenuItems an, verschwindet es an einer Stelle.
Wenn das MenuItem aber x:Shared="False" bekommt, dann ist das Problem beseitigt.

Kann mir einer erklären, was hier passiert? Was x:Shared bedeutet, weiß ich, aber warum kann ich nicht das selbe MenuItem-Objekt an zwei Stellen nutzen?
Und wie kann ich das bei meinem ursprünglichen Problem lösen? Die MenuItems werden im CodeBehind erstellt und in dem CollectionContainer abgelegt, somit kann ich das x:Shared nicht setzen.

Im Moment habe ich für beide ContextMenus jeweils einen CollectionContainer erstellt, die dann unterschiedliche MenuItems mit identischen Daten erhalten.
So funktioniert es, aber warum muss ich das machen, gibt es dafür keine bessere Lösung?

Beste Grüße

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

5.299 Beiträge seit 2008
vor 8 Jahren

Ich habe neuerdings mein Menü-System ins Viewmodel verlegt.
Also ich habe ein (baumartig strukturiertes) Menü-Viemodel, mit Bildern, Betextung und Commands, an die gebunden werden kann, und daran binde ich ein Menü, sodass die gewünschten MenüItems generiert werden.

Basierend auf dem Konzept kann man dieselben MenuViewmodelse auch in verschiedene Contextmenüsse einbinden etc..

Was bei dir ein CollectionContainer ist, und warum da MenuItems drinne sind - kann ich nicht nachvollziehen.
WpfControls sind normal eiglich nichts, was man in eigene Auflistungen einfüllt.

Der frühe Apfel fängt den Wurm.

Palladin007 Themenstarter:in
2.080 Beiträge seit 2012
vor 8 Jahren

Jedes MenuItem representiert eine Spalte im DataGrid. So sollen die Spalten ein- oder ausgeblendet werden können.
Da ich das in einem eigenen Control habe und diese MenuItems automatisch anhand der Spalten (die ja ebenfalls automatisch sind) generiert werden, habe ich das in der CodeBehind, ohne das je ein ViewModel ins Spiel kommt.
In einem ContextMenu sind aber noch mehr Elemente, unter den ColumnChooser-MenuItems sind ist dann noch ein Control angeordnet, das Filtern soll.
Der CollectionContainer hat dabei die Aufgabe, die Inhalte des ContextMenus voneinander zu trennen, sodass ich sie gesondert voneinander behandeln kann und nicht alles in der CodeBehind statt findet. So habe ich die Möglichkeit, die ColumnChooser-Items im CodeBehind zu generiert und der Rest wird in xaml angelegt.

Das ist aber auch gar nicht das Problem, das Problem ist, dass die ColumnChooser-MenuItems je Spalte nur einmal existieren und das ContextMenu kommt damit aus irgendeinem Grund nicht klar.
Wenn ich den CollectionContainer weg lasse und nur ein MenuItem betrachte, das in zwei verschiedenen ContextMenus genutzt wird, tritt ja das gleiche Problem auf.

PS:
Die Idee mit den Menü-ViewModels ist aber trotzdem ganz gut, die werde ich für mich auch übernehmen.
Allerdings nicht bei diesem Control, ich würde dabei ganz gerne ohne ViewModel bleiben ^^

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

S
469 Beiträge seit 2007
vor 8 Jahren

Eine Instanz eines Controls kann es immer nur an einer Stelle geben. Es hat nur einen Parent. Fügt man es an einer anderen Stelle hinzu, dann ändert sich der Parent und es ist an der alten Stelle logischerweise nicht mehr da.
Mit der Shared=false Eigenschaft erzwingst du, dass an jeder Stelle quasi eine eigene Instanz des Controls erzeugt wird. Deshalb funktioniert es dann mit mehreren Verwendungsstellen.
Die Lösung von ErfinderDesRades ist trotzdem sauberer, vorausgesetzt du hast Zeit und Muse um das umzusetzen.
Für einfache, private Anwendungen geht die Lösung mit dem Shared aber auch, man sollte sich halt im Kopf behalten, dass es eher Quick & dirty Praktik ist...

gruß
sth_Weird

++++++++++++++++++++~+
Fluchen ist die einzige Sprache, die jeder Programmierer perfekt beherrscht


Linux is for free...if your time is worth nothing
++++++++++++++++++++~+

Palladin007 Themenstarter:in
2.080 Beiträge seit 2012
vor 8 Jahren

Das erklärt es natürlich ...

So wie es ErfinderDesRades vorgeschlagen hat, finde ich das zwar gut, kann es aber nicht machen, weil die MenuItems sich aus den automatisch generierten Spalten des DataGrids zusammen setzen.
Ich hab dafür ein eigenes Control, was intern bei jeder Änderung der Spalten die MenuItems erstellt.
Wenn andere MenuItems dazu kommen, die ich in das ViewModel legen kann, werde ich das auch tun. Daher die komische Konstruktion mit den Collections, damit ich mehrere solche Quellen in ein ContextMenu zusammen fassen kann.

Ich danke auf jeden Fall für die Hilfe.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

5.299 Beiträge seit 2008
vor 8 Jahren

naja, auch für die HeaderTemplates eines Datagrids hab ich beizeiten schonmal ViewmodelKlassen angelegt...

Der frühe Apfel fängt den Wurm.

Palladin007 Themenstarter:in
2.080 Beiträge seit 2012
vor 8 Jahren

Naja, ich weiß ja nicht, ob das nicht über das Ziel hinaus schießt.
Der Umfang des Projektes rechtfertigt den Aufwand dann in keinster Weise, ich könnte mich wahrscheinlich auch genauso gut fragen, ob ich wirklich ViewModels brauche, oder ob das nicht overkill ist 😄

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.