Announcement

Collapse
No announcement yet.

EventHandler delegate "verliert" Daten?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • EventHandler delegate "verliert" Daten?

    Hallo,

    Der Titel ist nicht sehr genau, aber ich wüsste jetzt keine bessere Beschreibung der Problematik.
    Ich versuche es mal so genau wie möglich zu erklären:

    Mein Vorhaben
    Ich verwende DevExpress-Komponenten und generiere die MenuItems eines PopupMenu zur Laufzeit.
    Dabei gebe ich den Item-Komponenten einen EventHandler für das Click-Event mit.

    Generell habe ich das alles bereits umgesetzt und es funktioniert auch grundsätzlich.


    Die Grundlage
    Das Generieren eines Item und Zuweisen des EventHandlers führe ich innerhalb einer Helper-Klasse auf diese Weise durch:
    [highlight=csharp]
    // Create_DXMenuItem aus DevExpressHelper-Klasse:
    public DevExpress.Utils.Menu.DXMenuItem Create_DXMenuItem( String sCaption = "DXMenuItem_Template", String sValue = "" ) {

    DevExpress.Utils.Menu.DXMenuItem dxitem = new DevExpress.Utils.Menu.DXMenuItem( sCaption );
    dxitem.Click += delegate( object sender, EventArgs e ) {

    this.ChangeLanguage( sender, e, sValue );

    };

    }


    // ChangeLanguage aus DevExpressHelper-Klasse
    private void ChangeLanguage( object Sender, EventArgs e, String s ) {

    MessageBox.Show( s );


    }
    [/highlight]
    Mit dieser Konstellation funktioniert alles, wie es soll. Für jeden Menüpunkt, den ich anklicke wird der korrekte Wert in einer MessageBox angezeigt.

    Jetzt benötige ich aber innerhalb der Methode ChangeLanguage die Daten einer public-Property, der über einen Konstruktor ein externes Objekt zugewiesen wird.
    In der gesamten DevExpressHelper-Klasse habe ich alle Informationen dieses Objektes zur Verfügung, nur nicht in der ChangeLanguage()-Methode.
    Eine Eigenschaft des Objektes ist bspw. wieder ein Objekt, das die Zeilen einer Sicht verwaltet.

    Und genau darauf kann ich nun nicht mehr zugreifen, wenn ich bspw. die Methode so schreibe:
    [highlight=csharp]// ChangeLanguage aus DevExpressHelper-Klasse
    private void ChangeLanguage( object Sender, EventArgs e, String s ) {

    MessageBox.Show( this.InfoDaten.Zeilen[1].Felder("feld").ToString() );

    }[/highlight]
    bekomme ich einen NULL-Verweis um die Ohren. Das gilt für alle Vorhaben, die mit dem Objekt this.InfoDaten.Zeilen zu tun haben!
    An jeder anderen Stelle innerhalb der Klasse ist der Zugriff kein Problem.

    Auch andere Parameter/Eigenschaften sind kein Problem:
    [highlight=csharp]// ChangeLanguage aus DevExpressHelper-Klasse
    private void ChangeLanguage( object Sender, EventArgs e, String s ) {

    MessageBox.Show( this.InfoDaten.AnzahlZeilen.ToString() );

    }[/highlight]funktioniert ohne Fehler.

    Ich kann mir jetzt nicht erklären, warum ich auf das Zeilen-Objekt nicht mehr zugreifen kann?!

    Vielleicht hat jemand ne Ahnung, was das sein könnte bzw. hat auch eine andere Vorgehensweise für mich?
    Ich benötige das eigentlich nur, weil ich dem EventHandler einen Paramater mitgeben muß und soweit mir bekannt ist, geht das nur über delegates?!

    Danke für Tipps, Hilfen und Anregungen.
    Falls die Infos zu dürr sind, einfach nachfragen, ich wollte hier nur nicht zu viel externen Kram reinbringen, der nichts damit zu tun hat.

    Danke und Gruß
    Arne
    PHP rocks!
    Eine Initiative der PHP Community

  • #2
    Das übliche wäre das du zwei verschieden Instanzen von DevExpressHelper benutzt. Eine hast du benutzt um die Events zu verdrahten aber die Infodaten.Zeilen hast du an einer anderen Instanz von DevExpressHelper befüllt.

    Comment


    • #3
      Hallo Ralf,

      Danke für den Hinweis, aber ich glaube ich verstehe nicht ganz was Du meinst.
      die DevExpressHelper sieht derzeit auf die wichtigen Methoden begrenzt so aus:
      [highlight=csharp]public class DevExpressHelper {


      private clsInfoDaten InfoDaten;


      public DevExpressHelper( clsInfoDaten oDaten ) {

      this.InfoDaten = oDaten;
      MessageBox.Show( this.InfoDaten.Zeilen(1).Felder( "Sprachkennzeichen" ).Wert.ToString() ); // <-- Hier passt alles!

      }


      public DevExpress.Utils.Menu.DXPopupMenu Create_DXPopupMenu( String sCaption = "DXPopupMenu_Template" ) {

      DevExpress.Utils.Menu.DXPopupMenu dxpm = new DevExpress.Utils.Menu.DXPopupMenu();
      dxpm.Caption = sCaption;
      // ...more default values her

      return dxpm;

      }


      public DevExpress.Utils.Menu.DXMenuItem Create_DXMenuItem( String sCaption = "DXMenuItem_Template", String sValue = "" ) {

      DevExpress.Utils.Menu.DXMenuItem dxitem = new DevExpress.Utils.Menu.DXMenuItem( sCaption );
      dxitem.Click += ( sender, e ) => this.ChangeLanguage( sender, e, sValue );
      // ...more default values her

      return dxitem;

      }


      private void ChangeLanguage( object Sender, EventArgs e, String s ) {

      if ( this.InfoDaten.AnzahlZeilen > 0 ) {

      for ( int x=1; x<=this.InfoDaten.AnzahlZeilen; x++ ) {

      clsInfoDatenZeile oZeile = this.InfoDaten.Zeilen( x ); // <-- Hier kommt der NULL-Verweis
      String sSprachkennzeichen = oZeile.Felder( "Sprachkennzeichen" ).Wert.ToString();
      int iVariante = Convert.ToInt32( oZeile.Felder("AuspraegungID").Wert );

      if ( sSprachkennzeichen == sLanguageId && iVariante == iVariantId )
      iReturn = x;
      }

      }

      }

      }
      [/highlight]
      Die MessageBox im Konstruktor liefert den korrekten Wert, in der ChangeLanguage bekomme ich den NULL-Verweis?!
      Ich instanziiere die DevExpressHelper auch nur einmal.

      Gruß Arne
      PHP rocks!
      Eine Initiative der PHP Community

      Comment


      • #4
        Zeig doch mal die clsInfoDaten Klasse. Von deiner Beschreibung her müsste ja Infodaten.Zeilen null sein. Wie man den Zustand in dieser Klasse so herstellt kann man ohne diese Klasse schwer ermitteln.

        Ein Vermutung ist das du innerhalb von clsInfoDaten eine ganz normale Liste verwendest die 0-basiert ist. Deine Zeilen-methode rufst du aber mit einem Index auf der, aufgrund deines Code, 1-basiert scheint. Dann würde es beim Zugriff auf Zeilen(AnzahlZeilen) natürlich knallen weil du hinter die Liste guckst.
        Zuletzt editiert von Ralf Jansen; 14.10.2016, 19:51.

        Comment


        • #5
          Zeig doch mal die clsInfoDaten Klasse.
          Das Problem ist, dass ich die clsInfoDaten Klasse nicht zeigen kann. Zum einen, weil die nicht von mir ist und zum anderen, weil sie Core-Bestandteil der Software-Umgebung ist, in der ich entwickel, da komme ich so nicht ran.
          Ich kann allerdings garantieren, dass die Nutzung der Datentypen und Methodenaufrufen korrekt sind.

          Von deiner Beschreibung her müsste ja Infodaten.Zeilen null sein.
          Genau das wundert mich ja, weil ich ja im Konstruktor selber beim Testaufruf mit MessageBox kein NULL-Konflikt bekomme.
          Exakt derselbe Aufruf an jeder beliebigen Stelle der Klasse funktioniert auch. Es knallt ja eben nur in der ChangeLanguage() Methode, deshalb verstehe ich das ja auch nicht, denn InfoDaten sollte an der Stelle ja gleich wie an allen anderen Stellen sein.
          Daher hatte ich vermutet, dass es irgendetwas mit der Delegation zu tun hat.

          Deine Zeilen-methode rufst du aber mit einem Index auf der, aufgrund deines Code, 1-basiert scheint.
          Korrekt, alle Collections der Klasse sind 1-basiert.

          Dann würde es beim Zugriff auf Zeilen(AnzahlZeilen) natürlich knallen weil du hinter die Liste guckst.
          Schon, aber Zeilen(AnzahlZeilen) verwende ich ja nirgendwo und würde dann auch eher eine "ungültiger Index"-Meldung erwarten.
          Was ich verwende ist Zeilen(x) und x wird 1 basiert incrementiert, von daher bin ich konform.

          Vielleicht zur Erklärung: Wenn ich auf die View eine statische Funktion binde und den Code aus der ChangeLanguage() darin verwende, funktioniert das Script ja, von daher schliesse ich die clsInfoDaten Klasse eigentlich komplett aus, oder?

          Ich weiß, ist etwas komplizierter, weil ich nicht alle genutzten Klassen präsentieren kann, aber da ich wie gesagt das Problem mit der Delegation in Verbindung bringe, hoffe ich, hier ein paar hilfreiche Tipps zu bekommen.
          Danke, dass Du Dich damit auseinandersetzt!

          Gruß Arne
          PHP rocks!
          Eine Initiative der PHP Community

          Comment


          • #6
            Dann wird es schwer mit Ferndiagnose.
            Bei welchem Aufruf von this.InfoDaten.Zeilen(x) knallt es denn? Bei jedem x Wert bei einem speziellen x Wert? Hast du denn zumindest den Sourcecode der Klasse damit du selbst gucken kannst? Zeilen ist ja eine Methode es muss also was darin sein was konkret knallt. Und wo es in der Zeilen Methode knallt sollte die passenden Erkenntnisse liefern.

            Comment


            • #7
              Hallo,

              Ja, Ferndiagnose wird schwer, ich weiß :-)

              Also "knallen" tut es sofort bei Verwendung der Instanz Zeilen, egal welcher Index aufgerufen wird. Selbst das zulässige Count ist nicht nutzbar.
              Über this.InfoDaten.AnzahlZeilen bekomme ich ja saubere Werte. AnzahlZeilen liefert wie der Name schon sagt die Anzahl der Zeilen in der Sicht, welche ich dann über Zeilen() indexieren kann ( normalerweise! ).
              Heißt für mich eigentlich, dass er das gesamte Objekt Zeilen() nicht mehr kennt an der Stelle.

              Ich werde den Support der Schnittstelle nochmal auf die Füße treten, da ich mittlerweile denke, dass es kein Scope-Problem innerhalb C# ist.

              Danke für Deine Hinweise!
              Gruß Arne
              PHP rocks!
              Eine Initiative der PHP Community

              Comment

              Working...
              X