Raise Events nach oben durchreichen oder add Überladung funktioniert nicht

  • WPF

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

    Raise Events nach oben durchreichen oder add Überladung funktioniert nicht

    Hallo

    da ein Project mehr sagt als tausend Worte habe ich eins abgehangen. Ggf kommt es bekannt vor ;)

    Die Daten sind in einem Mehrstufigen Objectkonstukt untergebracht bzw die Struktur selbst stellt auch die Verdatung dar. Daher soll auch dies auch mit WPF bequem angezeigt werden.
    Das funktioniert bisher super.
    Also Personen als Listen in Gruppen diese wieder rum auch als Listen in einen Sammler
    Also die Klassen: c1_Person, c2_Gruppe, c3_Sammler
    Die dazugehörigen xaml: uc1Person, uc2Gruppe, uc3Sammler

    Nun habe ich ein Problem Clicks von der untersten Ebene (c1_Person/uc1Person vom ok Button) zur Hauptform zu bekommen. bzw die Info welches Element gedrückt wurde.
    Die Hauptform hat auch eine Ausgabe zur Anzeige. Das funktioniert leider nicht immer. Weils nicht ankommt

    Das Ganze wollte ich möglich kugelsicher machen, d.h. egal auf welche Art und Weise in bestimmten Funktionen Objekte angehangen werden, soll natürlich alles noch funktionieren. Also die Clickweiterleitungen
    Beim hinzufügen in die Listen werden dabei die addHandler aufgerufen um Verlinkungen zu bauen damit die Clicks bis zur Hauptform durchgereicht werden.
    also uc1Person>>viaRelayCommand>>c1_Person >>c2_Gruppe >> c3_Sammler >> MainWindow
    (eventuell ist es auch der falsche Weg und das macht man besser anders?)

    Das ist mir nur teilweise gelungen.
    c2..und c3..hatten ursprünglich List of(...) um die untergeordneten Elemente aufzunehmen.
    Damit ich zb ".add" der List Of T überladen konnte habe ich eine eigene Klasse c_myList angelegt welche von List of T auch erbt.
    Diese enthält gleichnamige add und addRange Funktionen. So richtig überschreiben geht wohl nicht.
    c2_gruppe und c3_sammler erben nun von c_mylist und haben keine eigenen Listen Propertys mehr.
    in c_mylist ist daher auch das Handler Prozedere untergebracht.

    Wie gesagt funktioniert nicht immer, je nachdem wie ich hinzufüge, und seh grad den Wald vor Bäume nicht.

    In der Hauptform in der Sub gentestdata habe ich zum testen ein paar Bsp angelegt.
    Beim starten des Projektes wird auch alles fertig aufgebaut. Items mit nicht funktionierenden Buttons sind mit "kein Click" gekennzeichnet.

    Hier zb ist es möglich über 2 verschiedene Syntaxe Items hinzuzufügen. Man sieht sie ja auch in der Ausgabe. Nur werden meine add Propertys/Funktionen umgangen und so die addHandler nicht ausgeführt.

    VB.NET-Quellcode

    1. '4------loop add einzeln-------------------------------------------------------
    2. Dim gr4 As New c2_Gruppe
    3. gr4.Name = "loop add einzeln"
    4. Dim p4a As c1_Person = genPerson("p4a", "loop", 0)
    5. Dim p4b As c1_Person = genPerson("p4b", "loop", 0)
    6. gr4.Add(p4a)
    7. gr4.Add(p4b)
    8. Dim gr4b As New c2_Gruppe
    9. For Each i In gr4.Item
    10. gr4b.Add(i) '<<geht
    11. Next
    12. For Each i In gr1.Item
    13. gr4b.Item.Add(i) '<<geht nicht. mit rechtsclick auf "add"und "gehe zur Defi" landet man auch in der Framework defi von "list". nicht in meiner Property
    14. Next
    15. myData.Add(gr4b)


    ggf ist das Ganze hier in WPF falsch einsortiert.
    Gruß Marc
    Dateien
    • Tester.zip

      (1,93 MB, 33 mal heruntergeladen, zuletzt: )
    Hallo @Prive

    Ich versuche mich mal daran wenns nix ausmacht 8-)

    Prive schrieb:

    Ggf kommt es bekannt vor

    Jep, da war mal was ;)

    Prive schrieb:

    Das Ganze wollte ich möglich kugelsicher machen

    Und genau hier lieg der Hase im Pfeffer. Zum einen machst zu hier und da was mit Binding, auf der anderen Seite aber greifst du von der CodeBehind auf das Grid zu. Beides in Kombi ist eher suboptimal und du wirst immer durcheinanderkommen was du nun mittels Binding hast und was über Code.

    Außerdem benötigst du deine List(Of T) gar nicht. Das muss alles nicht sein - das ganze AddHandler und sons zeugs ist auch nicht notwendig da es viel einfacher geht, aber nach der reihe.

    Du hast einen "Container" (rechts, das wo die die c1_Person nach dem Klick hinein sollen). In diesen "Container" willst du nun Objekte hineinpacken und evtl. wieder herausnehmen können.
    Nun gut, dann erstellst du dir solch einen Container und machst das auch. Also hast du links deine "Items" und rechts deinen "Container".

    Ich habe nun folgende Struktur in eine "MainWorkspace"-Klasse gepackt:


    Gut, wenn nun ein c1_Person die "Macht" haben soll etwas in diesen Container zu packen muss diese etwas von dem Container wissen, also übergebe ich im Konstruktor die Instanz des Containers.
    Von da an kann ein c1_Person mit dieser Collection hantieren und kann im Command einfach mit _container.Add(Me) sich selbst hinzufügen.
    Und du arbeitest wieder mit dem Luxus eines Commands und das funzt dann auch tadellos. Im View ist einfach ein ItemsControl an die Eigenschaft Container gebunden. Den Rest macht die WPF wieder für dich.

    Ich hoffe das war verständlich. Anbei das Projekt - ich habe versucht so viel Code von dir zu behalten und habe eben nicht großartig aufgeräumt.

    Schöne Grüße
    Sascha
    Dateien
    • Tester.zip

      (1,77 MB, 41 mal heruntergeladen, zuletzt: )
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo Sascha

    Danke für die Antwort. Habs schonmal kurz getestet. Sieht interessant aus.

    Aber das hatte ich garnicht vor. Aber trotzdem was gelernt. Kann ich ggf doch mal gebrauchen :D

    Rechts der Kasten ist lediglich als Detailansicht gedacht da die c1_person Klasse noch wesentlich mehr Propertys besitzt.
    Links halt sowas wie die Übersicht welche die Personen nur minimal zeigen soll, allerdings halt das ganze aktuelle ObjectBaum Konstrukt. Das geht ja gut.
    Die ürsprüngliche "c1_Personen" Quelle ist lediglich eine einfache Liste welche alle Personen ohne weiteren Zusammenhang speichert. Diese Liste bzw Personenitems wissen von nichts. Auf diese Personen werden aus allen Collections letzendlich verwiesen.

    Ich kann mich dunkel erinnern das irgendwann Visual Studio meine RaiseEvent Aktionen angemeckert hatte das man es dafür es garnicht missbrauchen sollte...alle möglichen objekte durch die Gegend schicken...aber ich weiss die Alternative nicht.
    Bisher hats diese "rückwärtsrouting" auch gut funktioniert . Nur wenn ich selbst zu vergesslich bin und einen Algorythmus was zusammenbauen lasse wo dann die Handler nicht gesetzt werden...such ich wieder ewig.
    OK, aber ich sehe hier jetzt keine Fragestellung.

    Was willst du dann? Vergiss AddHandler. Wenn es ohne geht dann bitte immer ohne. Und in meinem Beispiel ist es ohne.
    Was aus meinem Beispiel ist nun nicht so wie es sein soll? Bzw. was willst du machen?

    Wir brauchen eine richtige Fragestellung was nun dein konkretes Problem ist, dann finden wir sicher auch eine Lösung.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Das die c1_Person einen Blanko überwachten Container bekommt kann ich schon einbauen.
    Das vermischen von datenhaltung und "codebehind code"....ok das clickEvent von der xaml ist ja hier auch schon drin...irgendwie rutsch das alles ineinander. (jaja MVVM :P)
    mal ne Nacht drüber schlafen. Muss man sich vielleicht auch dran gewöhnen.

    Für diesen Anwendungsfall mags gehen. Ich sehe aber auch das Problem wenn ich was rein auf Logic Ebene, ohne xaml was machen will, dann währen Events wohl doch nötig um aktiv auf Änderungen in den Listen reagieren zu lassen.


    Gruß Marc

    Prive schrieb:

    Für diesen Anwendungsfall mags gehen. Ich sehe aber auch das Problem wenn ich was rein auf Logic Ebene, ohne xaml was machen will, dann währen Events wohl doch nötig um aktiv auf Änderungen in den Listen reagieren zu lassen.


    Was meinst du damit?
    Unter WinForms? Gut WPF und WinForms sind zwei verschiedene Dinge. So wie ich das Beispiel erstellt habe ist es eher Logisch als mit irgendwelchen Events.
    Will ich ein "Item" dort rüber haben, dann gebe ich es dort hinein. Will ichs wieder raus haben nehm ichs wieder raus. Wozu da mit Events arbeiten.

    Vorallem - Wehe du veriggt mal irgendwo mit RemoveHandler wieder rausnhemen. Du hast in deinem Beispiel auch kein IDisposable implementiert. Also wie und wo machst du RemoveHandler?
    Du hast also irgendwann 1000e Handler hinzugefügt und der GarbadgeCollector kann kein einziges Object von deinen Klasse "Aufräumen" weil noch ein Verweis (der Handler) darauf existiert. Zack -> OutOfMemoryException

    um aktiv auf Änderungen in den Listen reagieren zu lassen.

    Dann wohl eher 1x einen Handler auf die Container-Collection.Changed. So habe ich nur EINEN Handler gesetzt - das habe ich leichter im Griff - und bekomme jegliche änderungen mit. Die ObservableCollection unterstützt dies :rolleyes:

    Aber wie gesagt - So ganz ist mir noch nicht klar um was er dir nun genau geht. Vieleicht ist mein Ansatz auf vollkommen gaga weil ich nicht verstehe um was es geht. Kann sein.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Nofear23m schrieb:

    Was meinst du damit?
    Unter WinForms?


    Ja ich mein unabhängig von Winform oder WPF. Ohne Oberfläche nur innerhalb von Klassen.

    Mit den offenen Zeigern. Hm ja noch nie gehabt. Geht sowas? Also das es schlimm ist. Dachte das ist nur unter C# möglich da mit unsafe code/pointer gearbeitet werden kann. Ist wohl anderes Thema...:D

    Aber das mit den observ.Coll durchreichen scheint mir trotzdem ne gute Möglichkeit denk ich. Ich spinn mal kurz was zusammen:
    So als ne Art Bussystem. Jede angeschlossenes Object kann seine "EventNachrichten" reinkippen, und kann von mehreren auch ausgelesen werden. Und halt verarbeitet werden wenns passt :D. Ich frag mich wie die Reihenfolge da abläuft wenn mehrere beobachten. Wahrscheinlich hierarchisch.
    Frage ist nur wer löscht es wieder raus? Sonst wirds ja immer voller in der collection. Da nicht sicher ist das alle "Abonnenten" es ausgelesen haben....schwierig.
    Besser währe wohl wenn es nur eine Variable statt list währe.
    Kurz gegoogelt. hm könnte das hier sein:
    docs.microsoft.com/de-de/dotne…1?view=netframework-4.7.2
    Aber hab noch nichts ausprobiert.

    *Vollzitat entfernt* ~NoFear23m

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Nofear23m“ ()

    Hallo @Prive

    Sorry, ich stehe jetzt auf dem Schlauch wie es aussieht. Ich weis jetzt gar nicht mehr genau wovon du sprichst.
    Evtl. müsstest du ein Beispiel dafür machen.

    Dein Verlinkter MSDN Artikel ist ja die ObservableCollection, das hatte ich oben schon angesprochen.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##