Events variabel zuweisen



  • Guten Abend.

    Ich habe ein Panel, welchem ich verschiedene UserControls zuweisen möchte. Um per Button-Cklick aus den UserControls ein anderes Control aufzurufen arbeite ich mit einem Event welches ich den Controls zuweise. In meiner Form sieht die Event-Methode dann so aus:

    //Event in der Form, welche das Panel enthält
         public void f_SwitchFrm(UserControl New_uCon, UserControl Old_uCon)
         {
          if (New_uCon != null)
             {
                New_uCon.Dock = DockStyle.Fill;
                New_uCon.SwitchFrm += new FrmSwitchEventHandler(f_SwitchFrm);
    
                this.PanMain.Controls.Remove(Old_uCon);
                this.PanMain.Controls.Add(New_uCon);
             }
    
          else Close();
         }
    

    Auf der Seite der Controls ist das Event wie folgt implementiert:

    public unsafe delegate void FrmSwitchEventHandler(UserControl New_uCon, UserControl Old_uCon);
    public event FrmSwitchEventHandler SwitchFrm;
    
    //Ein Klick-Event in einem UserControl, welches ein anderes Control laden soll.
    private void btnAuswahl_Click(object sender, EventArgs e)
        {
           uconDefault nn = new uconDefault();
           SwitchFrm(nn, this);
        }
    

    Meine Frage: Wie bekomme ich es hin, "New_uCon" wieder dieses Event zuzuweisen?

    New_uCon.SwitchFrm += new FrmSwitchEventHandler(f_SwitchFrm);
    

    ...funktioniert nicht, da UserControl keine Methode SwitchFrm hat. Ach ne... Mit unsicherem Code habe ich es auch nicht hinbekommen (Zeiger auf UserControl geht scheinbar nicht?!). Und einen anderen Parameter möchte ich nicht unbedingt übergeben (z.B. Integer o.Ä. und mit Switch(int) die passenden Controls laden), da ich gerade versuche davon weg zu kommen 😞

    Sollte wer eine gute Idee / das passende Stichwort haben wäre ich sehr dankbar!

    MfG


  • Administrator

    Wieso übergibst du nicht die richtige Klasse statt einem UserControl ?

    Grüssli



  • Weil ich meine ganzen Controls in einer Benutzersteuerelement-Bib habe. Dann müsste ich ja für jedes Control ein eigenes Event machen. Das will ich ja vermeiden. Oder verstehe ich da jetzt was falsch?
    Meine bisher beste Idee war die:

    this.PanMain.Controls[0].Name += new FrmSwitchEventHandler(f_SwitchFrm);
    

    Bekomme ich aber eine NullRefException wenn das Control das Event aufruft. War mir auch fast klar, aber wie gesagt, war eben meine beste Idee.

    Trotzdem schonmal Danke!


  • Administrator

    Ok, ich gebe es offen zu. Ich habe keinen blassen Schimmer, wie dein Aufbau aussieht oder was du genau erreichen willst 😕

    Grüssli



  • Also: Mein Programm soll mit einer .dll arbeiten, welche alle meine UserControls enthält. Diese sollen in einem Panel des Programmfensters dargestellt werden und bilden quasi das eigentliche UI.
    Wird innerhalb eines solchen Controls z.B. ein Button angeklickt, soll ein anderes Control geladen werden (das ganze UI soll sich somit ändern). Da ich diesen Controls nicht erlauben will, selbst auf das Panel des Hauptfensters zuzugreifen, lösen Klick-Events (Buttons ect) ein selbst geschriebenes Event aus. Mit diesem möchte ich 2 Sachen übergeben: Zum einen das Control, welches als nächstes geladen werden soll, zum anderes das sendende Control.

    public delegate void FrmSwitchEventHandler(UserControl New_uCon, UserControl Old_uCon);
    

    In meinem Hauptfenster wird dieses Event registriert und es soll, abhängig von den Übergabewerten, das "alte" Control gelöscht und das "neue" dargestellt werden.

    public void f_SwitchFrm(UserControl New_uCon, UserControl Old_uCon)
            {
               New_uCon.Dock = DockStyle.Fill;
               this.PanMain.Controls.Remove(Old_uCon);
               this.PanMain.Controls.Add(New_uCon);
            }
    

    Mein Problem ist jetzt, dass ich New_uCon, also dem neuen Control aus der .dll-Datei, dieses Event nicht mehr zuweisen kann, da es von Control geerbt ist und damit das Event nicht zur Verfügung steht. Ich suche also nach einer Möglichkeit dem Control in meinem Panel das Event zuzuweisen, oder aber meine Parameter so zu übergeben, dass ich es einfach so zuweisen kann. Beispiele:

    //Dem Control im Panel das Event zuweisen
    (this.PanMain.Controls[0].Name).SwitchFrm+=new FrmSwitchEventHandler(f_SwitchFrm);
    
    //Oder dem Übergabeparameter das Event zuweisen
    New_uCon.SwitchFrm+=new FrmSwitchEventHandler(f_SwitchFrm);
    

    Beides Funktioniert leider so nicht und ich bin mit meinen Ideen langsam am Ende. Ich hoffe jetzt ist es deutlicher? Und danke schonmal für deine bisherigen Antworten!



  • Entweder übergibst du deinem Event schon die richtige Klasse (siehe Dravere) oder du musst nach dem Hinzufügen des neuen UserControls das Control auf den entsprechenden Typ casten und dann das Event zuweisen.



  • Hallo Doctore,

    hast du schon mal etwas von Interfaces oder Basisklassen gehört?
    Irgendwo mußt du doch das Event 'SwitchFrm' definiert haben. Damit man dann von einer anderen Klasse darauf zugreifen kann, muß dieses Event entweder eben direkt (so wie vorgeschlagen) über den Klassennamen oder eben über ein einheitliches Interface bzw. Basisklasse referenzierbar sein.

    interface ISwitchFrm
    {
      event FrmSwitchEventHandler SwitchFrm;
    }
    
    class MyUserControl : UserControl, ISwitchFrm
    {
      public event FrmSwitchEventHandler SwitchFrm;
    }
    
    class MainForm
    {
         public void f_SwitchFrm(UserControl New_uCon, UserControl Old_uCon)
         {
             if (New_uCon != null)
             {
                New_uCon.Dock = DockStyle.Fill;
    
                // check for ISwitchFrm
                ISwitchFrm switchFrm = New_uCon as ISwitchFrm;
                if (switchFrm != null)
                   switchFrm.SwitchFrm += new FrmSwitchEventHandler(f_SwitchFrm);
    
                this.PanMain.Controls.Remove(Old_uCon);
                this.PanMain.Controls.Add(New_uCon);
             }
             else
                 Close();
         }
    }
    


  • Old_uCon muss auch noch de abonniert werden, sonst bleibt es die ganze Zeit im Speicher und ist sogar noch aufrufbar


Anmelden zum Antworten