none
Event in parent von child auslösen RRS feed

  • Frage

  • Hallo,

    ich habe ein Event-Problem! Ich habe ein Projekt mit zwei Formen. Die erste ist „Form1“ und besitzt ein button1. Die zweite ist „Form2“ und besitzt ein „my_button“. Ich möchte durch klicken auf „my_button“ den Click-Event von „button1“ auslösen.

    Die erste Form "Form1" ist Parent-Form:

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace LoadFormTest
    {
        public partial class Form1 : Form
        {
            /// Declare new instance of Start_Form in the Main_Form
            Form2 Start_Form = new Form2();
                    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Shown(object sender, EventArgs e)
            {
                Point p = new Point(Location.X + Width / 2 - Start_Form.Width / 2, Location.Y + Height / 2 - Start_Form.Height / 2);           
                Start_Form.Show();
                Start_Form.SetLocation(p);
            }
    
            public void button1_Click(object sender, EventArgs e) 
            {
                MessageBox.Show("You fired up the Main Button click Event!", "Information");
            }
        }
    }

    Die zweite Form "Form2" ist Child-Form:

    using System; using System.Drawing; using System.Windows.Forms; namespace LoadFormTest { public partial class Form2 : Form { public Form2() { InitializeComponent(); } public void SetLocation(Point p) { this.Location = p; } /// Pass the Form1 instance to Form2 private Form1 m_parent; /// Declare Form1 as parent form public Form2(Form1 M_F) { InitializeComponent(); m_parent = M_F; } private void my_button_Click(object sender, EventArgs e) { //m_parent = new Form1(); //m_parent.button1_Click(sender, e); //my_button.Click += new System.EventHandler(m_parent.button1_Click); //m_parent.button1.PerformClick(); Hide(); } } }

    Wenn ich "button1_Click" in Form1 als public deklariere, kann ich in der zweiten Form mit

    "m_parent.button1_Click(sender, e);" darauf zugreifen.

    Bekomme aber: "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

    Habe es auch versucht mit

    "my_button.Click += new System.EventHandler(m_parent.button1_Click);"

    Damit bekomme ich:

    "Der Delegat einer Instanzenmethode kann kein "this" von NULL haben."

    In Debugger steht tatsächlich dass m_parent NULL ist. Mit "m_parent=new Form();" würde es funktionieren. Dadurch erstelle ich aber eine neue Form1. Kann mir bitte jemand helfen? Was mache ich falsch?


    Danke euch
    • Bearbeitet RauMa Donnerstag, 20. November 2014 12:20
    Donnerstag, 20. November 2014 12:20

Antworten

  • Hi,
    in Form2 erzeugst Du mit "m_parent = new Form1();" eine neue Instanz vom Typ Form1. Das aht aber mit dem ursprünglichen Form1 (=Instanz vom Typ Form1) nichts zu tun.

    Wenn Du auf Form2 auf Form1 zugreifen willst, benötigst Du in Form2 den Verweis auf die konkrete Form1-Instanz. Dafür gib1 es unterschiedliche Lösungswege:

    1. im Projekt liegt ein statischer Member, der in Form1 mit dem Verweis auf die Form1 (-Instanz) geladen wird, und, der in Form2 genutzt wird, um auf die Form1-Instanz zuzugreifen.

    2. die Form1 (-Instanz) übergibt einen Verweis auf sich selbst an die neu erzeugte Form2-Instanz (z.B. im Konstruktor oder über einen anderen Member).

     --
    Peter

    Donnerstag, 20. November 2014 14:26
  • Danke für die schnelle Antwort.

    Ich habe jetzt eine Lösung. In Child brauche ich:

    namespace LoadFormTest
    {
        public delegate void SomeEventHandler(object sender, EventArgs e);
    
        public partial class Form2 : Form
        {
            public event SomeEventHandler SomeEvent;
    
            public Form2()
            {
                InitializeComponent();
            }
    
            public void SetLocation(Point p)
            {
                this.Location = p;
            }
    
            private Form1 m_parent;
    
            public Form2(Form1 M_F)
            {
                InitializeComponent();
                m_parent = M_F;
            }
    
            public void my_button_Click(object sender, EventArgs e)
            {
                Hide();
                SomeEvent(sender, e);
            }
        }
    }

    In Parent:

    namespace LoadFormTest
    {
        public partial class Form1 : Form
        {
            Form2 Start_Form = new Form2();
                            
            public Form1()
            {
                InitializeComponent();
    
                Start_Form = new Form2();
                Start_Form.SomeEvent += new SomeEventHandler(childForm_SomeEvent);
            }
    
            void childForm_SomeEvent(object sender, EventArgs e)
            {
                button1.PerformClick();
            }
    
            private void Form1_Shown(object sender, EventArgs e)
            {
                Point p = new Point(Location.X + Width / 2 - Start_Form.Width / 2, Location.Y + Height / 2 - Start_Form.Height / 2);           
                Start_Form.Show();
                Start_Form.SetLocation(p);
            }
    
            private void button1_Click(object sender, EventArgs e) 
            {
                MessageBox.Show("You fired up the Main Button click Event!", "Information");
            }      
        }

    Damit funktioniert die ganze Sache.

    Nochmals danke,

    R.

    P.S. (evtl an Admin) Wie markiere ich die Frage als gelöst?

    Donnerstag, 20. November 2014 16:06

Alle Antworten

  • Hi,
    in Form2 erzeugst Du mit "m_parent = new Form1();" eine neue Instanz vom Typ Form1. Das aht aber mit dem ursprünglichen Form1 (=Instanz vom Typ Form1) nichts zu tun.

    Wenn Du auf Form2 auf Form1 zugreifen willst, benötigst Du in Form2 den Verweis auf die konkrete Form1-Instanz. Dafür gib1 es unterschiedliche Lösungswege:

    1. im Projekt liegt ein statischer Member, der in Form1 mit dem Verweis auf die Form1 (-Instanz) geladen wird, und, der in Form2 genutzt wird, um auf die Form1-Instanz zuzugreifen.

    2. die Form1 (-Instanz) übergibt einen Verweis auf sich selbst an die neu erzeugte Form2-Instanz (z.B. im Konstruktor oder über einen anderen Member).

     --
    Peter

    Donnerstag, 20. November 2014 14:26
  • Danke für die schnelle Antwort.

    Ich habe jetzt eine Lösung. In Child brauche ich:

    namespace LoadFormTest
    {
        public delegate void SomeEventHandler(object sender, EventArgs e);
    
        public partial class Form2 : Form
        {
            public event SomeEventHandler SomeEvent;
    
            public Form2()
            {
                InitializeComponent();
            }
    
            public void SetLocation(Point p)
            {
                this.Location = p;
            }
    
            private Form1 m_parent;
    
            public Form2(Form1 M_F)
            {
                InitializeComponent();
                m_parent = M_F;
            }
    
            public void my_button_Click(object sender, EventArgs e)
            {
                Hide();
                SomeEvent(sender, e);
            }
        }
    }

    In Parent:

    namespace LoadFormTest
    {
        public partial class Form1 : Form
        {
            Form2 Start_Form = new Form2();
                            
            public Form1()
            {
                InitializeComponent();
    
                Start_Form = new Form2();
                Start_Form.SomeEvent += new SomeEventHandler(childForm_SomeEvent);
            }
    
            void childForm_SomeEvent(object sender, EventArgs e)
            {
                button1.PerformClick();
            }
    
            private void Form1_Shown(object sender, EventArgs e)
            {
                Point p = new Point(Location.X + Width / 2 - Start_Form.Width / 2, Location.Y + Height / 2 - Start_Form.Height / 2);           
                Start_Form.Show();
                Start_Form.SetLocation(p);
            }
    
            private void button1_Click(object sender, EventArgs e) 
            {
                MessageBox.Show("You fired up the Main Button click Event!", "Information");
            }      
        }

    Damit funktioniert die ganze Sache.

    Nochmals danke,

    R.

    P.S. (evtl an Admin) Wie markiere ich die Frage als gelöst?

    Donnerstag, 20. November 2014 16:06
  • Hallo,
    die von dir selbst gepostete Lösung wollte ich dir auch gerade zeigen. So kannst du Ringabhängigkeiten in großen Projekten am besten vermeiden und hast i.d.R. weniger Probleme.

    Du kannst einen oder mehrere Posts über den "Als Antwort markieren" Link als Lösung markieren (unter den Beiträgen). Über den Pfeil neben den Beiträgen kannst du diese als Hilfreich bewerten.


    Tom Lambert - C# MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Donnerstag, 20. November 2014 16:14
    Moderator