[C#] Form1.toolStripStatusLabel1 ändern aus anderer Klasse heraus?

Nein. Du hast versucht das Form.Load Ereigniss mit einer Methode zu verknüpfen, welche nicht der dafür benötigten Methodensignatur entspricht (Parameter).

Dann versuchst Du schonwieder ein statisches Objekt aufzurufen, was nicht vorhanden ist (idea.Pinger.PingFinishedEventHandler). Dir fehlen die Grundlagen zur OOP. Kauf Dir bitte unbedingt ein Buch darüber und schau in den Stickie den ich eben gepostet habe. :)

Beleibt jetzt nur noch die Frage ob Du das Ereigniss von deinem Pinger oder von dem Form erledigen lassen willst. Wenn in deinem Form, dann machst es so:

Im Form:
C#:
class MyForm : Form
{
    Pinger m_pinger;

    MyForm ()
    {
        m_pinger = new Pinger();
        m_pinger.PingFinished += new idea.Pinger.PingFinishedEventHandler( this.m_pinger_PingFinished );
    }

    void m_pinger_PingFinished( object sender, string pinged_host )
    {
        this.Invoke( PingFinished( pinged_host ) );
    }

    void PingFinished( string pinged_host )
    {
        // event handling goes here
    }
}

Im Pinger:
C#:
class Pinger
{
    public delegate void PingFinishedEventHandler(object sender, string pinged_host);

    public event PingFinishedEventHandler PingFinished;

    Control eventSubscriberControl;
    public Control EventSubscriberControl {
        get { return eventSubscriberControl; }
        set { eventSubscriberControl= value; }
    }
        
    public void do_ping()
    {
        [...]
        if ( eventSubscriberControl == null )
            PingFinished( this, host );
        else( eventSubscriberControl != null && eventSubscriberControl .InvokeRequired )
            eventSubscriberControl.Invoke( PingFinished, new object[] { this, host } );
    }
}

Btw. Namespaces schreibt man aber auch groß. Schau Dir am besten deine Programme immer mit FXCop an. ;)

//Edit: Dem Property musst aber noch das Form zuweisen:
C#:
MyForm : Form
{
    MyForm ()
    {
        m_pinger = new Pinger();
        m_pinger.EventSubscriberControl = this;
        m_pinger.PingFinished += new idea.Pinger.PingFinishedEventHandler( this.m_pinger_PingFinished );
    }
}
 
Zuletzt bearbeitet:
Tut mir leid dass ich nerve, aber ich bin offensichtlich echt zu blöd dazu.

m_pinger_PingFinished in Form1 bekommt den Hostnamen anscheinend nicht.

Form1:
C#:
public partial class Form1 : Form
    {
        Pinger m_pinger;
        public Form1()
        {
            InitializeComponent();
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.SelectedImageIndex == 0)
            {
                m_pinger = new Pinger(e.Node.Text);
                m_pinger.EventSubscriberControl = this;
                m_pinger.PingFinished += new idea.Pinger.PingFinishedEventHandler(this.m_pinger_PingFinished);
                

                Thread t = new Thread(new ThreadStart(m_pinger.do_ping));
                t.Start();
            }
            else if (e.Node.SelectedImageIndex == 1)
            {
                MessageBox.Show("Raum ausgewählt");
            }
        }
        void m_pinger_PingFinished( object sender, string pinged_host )
        {
            this.Invoke( PingFinished( pinged_host ) );
        }
        void PingFinished( string pinged_host )
        {
        // event handling goes here
            MessageBox.Show("Ping finished");
        }
    }

und die pinger.cs
C#:
class Pinger
    {
        private string host;
        public Pinger(string host_str)
        {
            host = host_str;
        }

        public delegate void PingFinishedEventHandler(object sender, string pinged_host);
        public event PingFinishedEventHandler PingFinished;
        Control eventSubscriberControl;
        public Control EventSubscriberControl {
            get { return eventSubscriberControl; }
            set { eventSubscriberControl= value; }
        }

        public void do_ping()
        {
            try
            {
                Ping pingSender = new Ping();
                PingOptions options = new PingOptions();

                // Use the default Ttl value which is 128,
                // but change the fragmentation behavior.
                options.DontFragment = true;

                // Create a buffer of 32 bytes of data to be transmitted.
                string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
                byte[] buffer = Encoding.ASCII.GetBytes(data);
                int timeout = 120;
                PingReply reply = pingSender.Send(host, timeout, buffer, options);
                string message = "";
                if (reply.Status == IPStatus.Success)
                {
                    message += "Address: " + reply.Address.ToString();
                    message += "\nRoundTrip time: " + reply.RoundtripTime;
                    message += "\nTime to live: " + reply.Optionsl;
                    message += "\nDon't fragment: " + reply.Options.DontFragment;
                    message += "\nBuffer size: " + reply.Buffer.Length;
                }
                System.Windows.Forms.MessageBox.Show(message);
            }
            catch
            {
                System.Windows.Forms.MessageBox.Show("PC aus.");
            }
            if (eventSubscriberControl == null)
                PingFinished(this, this.host);
            else if( eventSubscriberControl != null && eventSubscriberControl .InvokeRequired )
                eventSubscriberControl.Invoke(PingFinished, new object[] { this, host });
            PingFinished(this, host);
            System.Threading.Thread.CurrentThread.Abort();
        }
    }

Ich verstehe ja die Sache mit public,private usw (kenne ich von php), aber das Zusammenspiel mehrerer Klassen ist echt neu...
 
Zuletzt bearbeitet:
Das ist absolut nicht schlimm. Alle Anfang ist schwer, bei war das erst ein Gefrickel kann ich dir sagen. :D

So, setze mal einen Breakpoint am Anfang deiner do_ping Methode. Wenn der Brakpint erreicht ist, drückst solange F11 bis Du im Form angekommen bist und überwachst mal den Inhalt der Variablen, indem Du mit der Maus darüber gehst. Alternativ hast ja dafür noch die Überwachungsfenster im VS. Die findest im Menu Debug.

Ich kann auf den ersten Hieb gar nichts Falsches erkennen. Und ich muss Dir leider sagen, dass Du hier mit Copy & Paste nicht viel lernst. Das ist hier nicht wie im PHP Forum, sorry. Hier ist Initiative gefragt um sich auf das wesentliche konzentrieren zu können. Außerdem lernt man so viel besser. :) Zudem hast ja den IntelliSense zu Verfügung. Und wenn Du mit den Entsprechenden CodingStyles arbeitest, wird das ein Kinderspiel. Total krass wird es erst wenn Du Dir mal den ReSharper angeschaut hast. Dann kannst gar nicht mehr ohne. :D

Also dann schönen Abend noch, bis morgen.

//Edit: Ach, ganz vergessen: VisualStudioShortcuts - PDF.
 
Zuletzt bearbeitet:
Danke für die aufmunternden Worte!
Ich hab mal Breakpoints gesetzt, aber es hilft nichts, mein Projekt wird nicht kompiliert, Fehler liegt in z.28 Form1, da pingFinished() ungültige Argumente übergeben werden, wahrscheinlich void.

Ich mach Schluss für heute, mein Kopf raucht...
 
Na, mittlerweile weiter gekommen?

Btw. ich habe gerade gesehen, dass die 52 Zeile aus deinem letztem Code Snippet überflüssig ist (pinger.cs).
Und was ist denn die 28. Zeile in deinem Form1? Fehlt es Dir an Kommentaren in meinen Snippets oder soll ich Dir mal eine Demo machen?
 
Mein Problem ist das ich zwar die Logik verstehe, also dass die Pinger.cs ein Event startet, was dann Form1.cs "abfängt", aber ich kann das halt nicht in Code fassen und verstehe den Code deshalb auch nicht. Habe jetzt zeitweise ein anderes Programm geschrieben (eine Art Kurzzeitwecker), um ein bisschen in die OOP hineinzukommen.
Das läuft sogar!
Ich habe dort Form1 in der ein Timer runterzählt und gleichzeitig ein anderer Timer Änderungen in einem Registry-Schlüssel überwacht.
Form2 ist ein "Einstellungen"-Fenster, das diese Änderungen durchführt. Theoretisch könnte Form2 auch ein Event auslösen, damit Form1 benachrichtigt wird, oder?

Könntest du dir mal das Projekt ansehen und mir die Event-Variante zeigen (also wo genau das Event erzeugt wird, ausgelöst und in Form1 abboniert bzw drauf reagiert?)

Wahrscheinlich verstehe ich das besser, da dieses Programm etwas weniger komplex ist...
Wenn du noch Codeverbesserungen siehst, her damit!

C# habe ich mir übrigends mit einem Buch namens "Visual C# 2005 für Kids" beigebracht. Dort wird vieles von der "Logik" der OOP klar, aber auf Threading, mehrere Fenster, Events usw wird nicht eingegangen (okay, wenn man das kleine Thread.Sleep() nicht mitzählt).
Kennst du ein gutes (E)book/Tutorial, dass das für einen "Anfänger" erklärt?

Hier der Code, da das Projekt 400KB groß ist:
Form1
C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;  // DllImport()
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;

namespace Timer
{
    public partial class Form1 : Form
    {
        int timer_min;
        int timer_sec;
        string sound;
        Form2 f2 = new Form2();

        public Form1()
        {
            InitializeComponent();
            load_settings_from_reg();
            settimer(timer_min,timer_sec);
            timer2.Start();
        }

        private void load_settings_from_reg()
        {
            // Attempt to open the key
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Florian Klink\\Timer\\");

            // If the return value is null, the key doesn't exist
            if (key == null)
            {
                // The key doesn't exist; create it / open it
                key = Registry.CurrentUser.CreateSubKey("Software\\Florian Klink\\Timer\\");
                key.SetValue("timer_min", "5");
                key.SetValue("timer_sec", "0");
                key.SetValue("sound", "bell.wav");
            }
            timer_min = Int32.Parse(key.GetValue("timer_min").ToString());
            timer_sec = Int32.Parse(key.GetValue("timer_sec").ToString());
            sound = key.GetValue("sound").ToString();
            if(sound=="bell.wav")
            {
                sound=Application.StartupPath+"\\bell.wav";
            }
            key.Close();
        }

        private void settimer(int timer_min, int timer_sec)
        {
            label1.Text = doublezero(timer_min);
            label3.Text = doublezero(timer_sec);
            notifyIcon1.Text = "Restzeit: " + label1.Text + ":" + label3.Text;
        }

        private string doublezero(int input)
        {
            string inputstr=input.ToString();
            switch (inputstr)
            {
                case "0":
                    inputstr = "00";
                    break;
                case "1":
                    inputstr = "01";
                    break;
                case "2":
                    inputstr = "02";
                    break;
                case "3":
                    inputstr = "03";
                    break;
                case "4":
                    inputstr = "04";
                    break;
                case "5":
                    inputstr = "05";
                    break;
                case "6":
                    inputstr = "06";
                    break;
                case "7":
                    inputstr = "07";
                    break;
                case "8":
                    inputstr = "08";
                    break;
                case "9":
                    inputstr = "09";
                    break;
            }
            
            return inputstr;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (label1.Text == "00" && label3.Text == "00")
            {
                //see bottom
            }
            else
            {
                if (label3.Text == "00")//0 seconds
                {
                    label1.Text = doublezero(Int32.Parse(label1.Text)-1);
                    label3.Text = "59";
                }
                else
                {
                    label3.Text = doublezero(Int32.Parse(label3.Text) - 1);
                }
            }
            notifyIcon1.Text = "Restzeit: "+label1.Text+":"+label3.Text;
            if (label1.Text == "00" && label3.Text == "00")
            {
                Thread ringer = new Thread(new ThreadStart(ring));
                ringer.Start();
                startpause("pause");
                
            }

        }
        private void ring()
        {
            WSounds ws = new WSounds();
            ws.Play(sound, ws.SND_FILENAME | ws.SND_ASYNC);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                showhide();
            } 
        }

        private void showhide()
        {
            if (this.Visible)
            {
                this.Hide();
            }
            else
            {
                this.Show();
            }
        }

        private void startpause()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            if (timer1.Enabled)
            {
                timer1.Stop();
                pauseToolStripMenuItem.Text = "Resume";
                pauseToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("resumeToolStripMenuItem.Image")));
            }
            else
            {
                timer1.Start();
                pauseToolStripMenuItem.Text = "Pause";
                pauseToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("pauseToolStripMenuItem.Image")));
            }
        }

        private void startpause(string action)
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            if (action == "check")
            {
                if (timer1.Enabled)
                {
                    pauseToolStripMenuItem.Text = "Pause";
                    pauseToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("pauseToolStripMenuItem.Image")));
                }
                else
                {
                    pauseToolStripMenuItem.Text = "Resume";
                    pauseToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("resumeToolStripMenuItem.Image")));
                }
            }
            else if (action == "start")
            {
                timer1.Start();
                pauseToolStripMenuItem.Text = "Pause";
                pauseToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("pauseToolStripMenuItem.Image")));
            }
            else if (action == "pause")
            {
                timer1.Stop();
                pauseToolStripMenuItem.Text = "Resume";
                pauseToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("resumeToolStripMenuItem.Image")));
            }
        }

        private void openWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            showhide();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Application.ProductName + "\nv" + Application.ProductVersion + "\n©" + DateTime.Now.Year + " Florian Klink\nAll rights reserved.", "About");
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            showhide();
        }

        private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            startpause();
        }

        private void resetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            startpause("pause");
            settimer(timer_min, timer_sec);
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            f2.ShowDialog();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            f2.Close();
            Application.Exit();
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            // Attempt to open the key
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Florian Klink\\Timer\\");
            int new_timer_min = Int32.Parse(key.GetValue("timer_min").ToString());
            int new_timer_sec = Int32.Parse(key.GetValue("timer_sec").ToString());
            string new_sound = key.GetValue("sound").ToString();
            key.Close();
            if (timer_min != new_timer_min || timer_sec != new_timer_sec)
            {
                load_settings_from_reg();
                startpause("pause");
                settimer(timer_min, timer_sec);
            }
            if (sound != new_sound)
                sound = new_sound;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                this.Hide();
            }
            startpause("pause");
        }
    }
    public class WSounds
    {
        [DllImport("WinMM.dll")]
        public static extern bool PlaySound(string fname, int Mod, int flag);

        // these are the SoundFlags we are using here, check mmsystem.h for more
        public int SND_ASYNC = 0x0001;     // play asynchronously
        public int SND_FILENAME = 0x00020000; // use file name
        public int SND_PURGE = 0x0040;     // purge non-static events

        public void Play(string fname, int SoundFlags)
        {
            PlaySound(fname, 0, SoundFlags);
        }

        public void StopPlay()
        {
            PlaySound(null, 0, SND_PURGE);
        }
    }
}
form2
C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Reflection;
using System.Security;
using System.Security.AccessControl;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;

namespace Timer
{
    public partial class Form2 : Form
    {
        int timer_min;
        int timer_sec;
        string sound;
        public Form2()
        {
            InitializeComponent();
        }
        private string doublezero(int input)
        {
            string inputstr = input.ToString();
            switch (inputstr)
            {
                case "0":
                    inputstr = "00";
                    break;
                case "1":
                    inputstr = "01";
                    break;
                case "2":
                    inputstr = "02";
                    break;
                case "3":
                    inputstr = "03";
                    break;
                case "4":
                    inputstr = "04";
                    break;
                case "5":
                    inputstr = "05";
                    break;
                case "6":
                    inputstr = "06";
                    break;
                case "7":
                    inputstr = "07";
                    break;
                case "8":
                    inputstr = "08";
                    break;
                case "9":
                    inputstr = "09";
                    break;
            }

            return inputstr;
        }

        private void load_settings_from_reg()
        {
            // Attempt to open the key
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Florian Klink\\Timer\\");
            timer_min = Int32.Parse(key.GetValue("timer_min").ToString());
            timer_sec = Int32.Parse(key.GetValue("timer_sec").ToString());
            sound = key.GetValue("sound").ToString();
            if(sound=="bell.wav")
            {
                sound=Application.StartupPath+"\\bell.wav";
            }
            key.Close();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Florian Klink\\Timer\\",true);
            /*
            string user = Environment.UserDomainName + "\\" + Environment.UserName;
            RegistrySecurity rs = new RegistrySecurity();
            rs.AddAccessRule(new RegistryAccessRule(user,
            RegistryRights.ReadKey | RegistryRights.Delete,
            InheritanceFlags.None,
            PropagationFlags.None,
            AccessControlType.Allow));*/
            key.SetValue("timer_min",doublezero(Int32.Parse(numericUpDown1.Value.ToString())).ToString());
            key.SetValue("timer_sec", doublezero(Int32.Parse(numericUpDown2.Value.ToString())).ToString());
            key.SetValue("sound", textBox1.Text);
            key.Close();
            Close();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            load_settings_from_reg();
            numericUpDown1.Value = timer_min;
            numericUpDown2.Value = timer_sec;
            textBox1.Text = sound;
        }

        private void numericUpDown1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                button1_Click(sender, e);
            }
        }

        private void numericUpDown2_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                button1_Click(sender, e);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog().ToString() == DialogResult.OK.ToString())
            {
                sound = textBox1.Text = openFileDialog1.FileName;
            }
        }
    }
}
 
Zuletzt bearbeitet:
Zurück