Forum: PC-Programmierung [C#] Form1 Funktion aus Form2 aufrufen


von TL431 (Gast)


Lesenswert?

Habe eine Funktion "private bool SendCommand(...)" in Form1.cs die ich 
in Form2.cs benutzen will. Wenn ich das mit "Form1.SendCommand(...)" 
machen will, sagt er mir das das aufgrund der Sicherheitsebene nicht 
möglich ist. Was muss ich tun damit's klappt?

Benutze C# Express 2008.

von Matthias L. (matze88)


Lesenswert?

Die Funktion public deklarieren... Aber eigentlich ist es böse, 
Formularfunktionen aus nem anderen Formular aufzurufen. Eventuell kannst 
du das ganze von dem Formular abspalten und in eine dritte Datei packen, 
die in beiden Formularen genutzt wird?

Ist das natürliche eine Schnittstelle zum Formular, so wäre das auch so 
in Ordnung.

von TL431 (Gast)


Lesenswert?

>Die Funktion public deklarieren...
Damit gibt's jetzt die Fehlermeldung:
>Für das nicht statische Feld, die Methode oder die
>Eigenschaft "....SendCommand(...)" ist ein Objektverweis erforderlich.


>Eventuell kannst du das ganze von dem Formular abspalten und in eine
>dritte Datei packen, die in beiden Formularen genutzt wird?
Das wäre mir eigentlich sogar am liebsten :)
Kann ich dafür die "Programm.cs" nehmen die C# schon angelegt hat?

von TL431 (Gast)


Lesenswert?

Hat noch einer eine Idee wegen der Fehlermeldung?

von Karl H. (kbuchegg)


Lesenswert?

TL431 schrieb:
> Hat noch einer eine Idee wegen der Fehlermeldung?

Die sollte doch eigentlich selbsterklärend sein.

Wenn du die Funktion xyz aus der Form1 aufrufen willst, dann brauchst du 
zuerst mal das Form Objekt um dafür eine Memberfunktion aufzurufen.
Du kannst nicht einfach irgendwelche Funktionen aufrufen! Die Funktion 
ist Bestandteil eines Objektes und um die Funktion rufen zu können 
benötigst du das Objekt.

von TL431 (Gast)


Lesenswert?

Objekte und Memberfunktionen sind leider böhmische Dörfer für mich :)

Hab's aber inzwischen hinbekommen.
Für alle die es interessiert:

Form1:
1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Text;
7
using System.Windows.Forms;
8
9
namespace Projektname
10
{
11
    public partial class Form1 : Form
12
    {
13
14
15
        public bool SendCommand(...)
16
        {

Form2:
1
using System;
2
using System.Collections.Generic;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Text;
7
using System.Windows.Forms;
8
9
10
namespace Projektname
11
{
12
    public partial class Form2 : Form
13
    {
14
        Projektname.Form1 Beliebig = new Form1();
15
16
17
        private void Button_Send_Click(object sender, EventArgs e)
18
        {
19
           // Funktion aus Form1 aufrufen
20
           Beliebig.SendCommand(...);

von TL431 (Gast)


Lesenswert?

Neues Problem.
Die Funktion in Form1 (SendCommand) öffnet den COM Port. Wenn ich aus 
Form1 den COM Port mit "SendCommand" öffne und offen lasse und dann die 
Funktion von Form2 aus aufrufe leifert "SerialPort.IsOpen" plötzlich 
nicht true sondern false zurück.
Was ist das nun wieder? Muss ich den SerialPort in Form2 auch noch 
irgendwie "bekannt geben"?

von Ralf (Gast)


Lesenswert?

Ich glaub es liegt daran, dass du in Form1 ein neues Objekt Form1 
erzeugst.
Neue Form1 = neues SerialPort-Objekt.
Neues Serialport-Objekt = geschlossener COM-Port

Was du brauchst ist eher sowas:
1
public partial class Form2 : Form
2
    {
3
        SerialPort Form1SerialPort = Form1.SerialPortObjektName;
4
        ...
5
    }
Allerdings wird das so wie ich es geschrieben hab, wahrscheinlich nicht 
tun, du brauchst einen Verweis auf das SerialPort Objekt.

Ralf

von TL431 (Gast)


Lesenswert?

Also ich hab den SerialPort einfach nur per Drag&Drop in das Form1 
eingefügt. Sowas wie "Neue Form1 = neues SerialPort-Objekt." hab ich 
nicht.

von TL431 (Gast)


Lesenswert?

Hab grad noch ein Beispielprojekt mit SerialPort und mehreren cs Dateien 
gefunden. Werd mal sehen ob ich da was abschauen kann....

von Karl H. (kbuchegg)


Lesenswert?

TL431 schrieb:
> Also ich hab den SerialPort einfach nur per Drag&Drop in das Form1
> eingefügt. Sowas wie "Neue Form1 = neues SerialPort-Objekt." hab ich
> nicht.

Das ist auch kein Programmtext, sondern eine verküzte Schreibweise für 
"Ein neues Form Objekt bedeutet auch, dass ein neues SerialPort Objekt 
generiert wird, da ja jedes Form1 Objekt sein eigenes SerialPort Objekt 
enthält"

von TL431 (Gast)


Lesenswert?

Hab es jetzt auch mal über "SerialPort COMPort = new SerialPort();" 
eingebunden, aber das macht auch keinen Unterschied :(

Grundsätzlich ist das aber schon möglich das ich einen SerialPort von 
Form1 in Form2 benutzen kann, oder wie stellt man das an?

von Arc N. (arc)


Lesenswert?

TL431 schrieb:
> Hab es jetzt auch mal über "SerialPort COMPort = new SerialPort();"
> eingebunden, aber das macht auch keinen Unterschied :(
>
> Grundsätzlich ist das aber schon möglich das ich einen SerialPort von
> Form1 in Form2 benutzen kann, oder wie stellt man das an?

Zwei Beispiele in denen nur ein einziges SerialPort-Objekt existiert:
1
class Form1 : Form {
2
    static SerialPort mSerialPort = new SerialPort();
3
    public static SerialPort Serial {
4
        get { return mSerialPort; }
5
    }
6
}
7
8
class Form2 : Form {
9
    public void DoSomething() {
10
        Form1.Serial.Open()
11
    }
12
}
13
14
// oder etwas wartungsfreundlicher
15
16
internal class Serial {
17
    static SerialPort mSerialPort = new SerialPort();
18
    public static void Open() {
19
        mSerialPort.Open();   
20
    }
21
    public static void Send(string msg) {
22
        mSerialPort.Write(msg);
23
    }
24
}
25
26
class Form1 : Form {
27
    public void DoSomething1() {
28
        Serial.Send("abcdefg"); 
29
    }
30
}
31
32
class Form2 : Form {
33
    public void DoSomething2() {
34
        Serial.Send("123456"); 
35
    }
36
}
37
38
// Synchronisation, falls mehrere Threads darauf zugreifen sollen,
39
// fehlt in beiden Fällen...

von TL431 (Gast)


Lesenswert?

Isch werd verrückt, der geehht :)
Mit
static SerialPort COMPort = new SerialPort();
funktioniert's jetzt endlich...

Danke an alle :)

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Du kannst diese ganzen Probleme umgehen wenn du die Benutzeroberfläche 
von der Datenhaltung sauber trennst. Also ein einziges Objekt dass deine 
Funktionen enthält die du in den beiden Forms brauchst.

von TL431 (Gast)


Lesenswert?

Hatte schon mal versucht die Funktionen in "Program.cs" zu platzieren. 
Da hab ich aber wohl das gleiche Problem das die von anderen Forms nicht 
ohne weiteres sichtbar sind...

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Von der Program.cs solltest du auch die Finger weglassen.
Erstele dir eine eigene Klasse um das sauber zu trennen.
wenn es nicht klappt. hänge am besten das komplette projekt an, dann 
kann dir einfacher geholfen werden.

von pitchy (Gast)


Lesenswert?

Hallo,

die Lösung von Arc Net funktioniert "nur" solange man Daten sendet. Ich 
will nun aber Daten von einer ext. Unit empfangen und im jeweilig 
aktiven Formualar anzeigen.

das Ganze soll so aussehen:

Class Form1: Befehl Temperatur senden und Antwort im aktiven Formular1
             anzeigen

Class Form2: Befehl Geschwindigkeit senden und Antwort im aktiven 
Formular2
             anzeigen

Class FormX:  u.s.w.

Wie kann ich ein DataReceived / ReadExisting Ergebnis aus der Class 
Serial in ein Form übergeben?

Vielen Dank an Alle für dringend benötigte Hilfe

Uwe

von Karl H. (kbuchegg)


Lesenswert?

pitchy schrieb:
> Hallo,
>
> die Lösung von Arc Net funktioniert "nur" solange man Daten sendet. Ich
> will nun aber Daten von einer ext. Unit empfangen und im jeweilig
> aktiven Formualar anzeigen.
>
> das Ganze soll so aussehen:
>
> Class Form1: Befehl Temperatur senden und Antwort im aktiven Formular1
>              anzeigen
>
> Class Form2: Befehl Geschwindigkeit senden und Antwort im aktiven
> Formular2
>              anzeigen
>
> Class FormX:  u.s.w.
>
> Wie kann ich ein DataReceived / ReadExisting Ergebnis aus der Class
> Serial in ein Form übergeben?

Indem du der Class Serial eine Interface eines Datenempfängers bekannt 
machst, der die Daten annimmt.
Die Form, welche die Daten anzeigen soll, implementiert die Funktionen 
des Interfaces und wird beim Serial Objekt als Datenempfänger 
registriert.

(Und nur damit es keine Missverständnisse gibt: Du als Programmierer 
definierst, wie dieses Interface auszusehen hat)

von pitchy (Gast)


Lesenswert?

Danke für die schnelle Antwort.

Vom Prinzip her verstanden. Ich habe aber leider keine Ahnung
wie das Ganze als Code in der Class Serial und im entsprechenden Form
ausssehen muss.

Bisher habe ich nur innerhalb einer Form senden und empfangen 
realisiert.

using System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace rs232_mobile
{
    using System.IO.Ports;
    public partial class seriell : Form
    {
        public string empfang = null;
        public SerialPort port = new SerialPort();
        public seriell()
        {
            InitializeComponent();
            port.DataReceived += new 
SerialDataReceivedEventHandler(port_DataReceived);
            port.PortName = "COM1";
            port.BaudRate = 9600;
            port.DataBits = 8;
            port.Parity = Parity.None;
            port.StopBits = StopBits.One;
        }
        private void seriell_Load(object sender, EventArgs e)
        {
            if (port.IsOpen == false)
                try
                {
                    port.Open();
                }
                catch (Exception oex)
                {
                    MessageBox.Show(oex.ToString());
                }
        }
        public void port_DataReceived(object sender, 
SerialDataReceivedEventArgs e)
        {
            this.Invoke(new EventHandler(DoUpdate));
        }
        public void DoUpdate(object s, EventArgs e)
        {
            empfang = port.ReadExisting();
            textBox1.Text = textBox1.Text + empfang + "\n";
        }
        public void Port_Open(object sender, EventArgs e)
        {
            if(port.IsOpen == false)
                try
                {
                    port.Open();
                }
                catch (Exception oex)
                {
                    MessageBox.Show(oex.ToString());
                }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            port.WriteLine("Hallihallo");
        }
        private void menuItem1_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
        }
    }
}

Teile des Codes funktionieren nur innerhalb einer Form aber nicht 
innerhalb einer "einfachen" Class ohne Form.

von pitchy (Gast)


Lesenswert?

Hallo,

kann mir jemand ein entsprechendes Codebeispiel geben wie
so ein Interface auszusehen hat. So dass ich aus irgend einer
Form auf empfangene Daten zugreifen kann.

Besten Dank!

Uwe

von Arc N. (arc)


Lesenswert?

pitchy schrieb:
> Hallo,
>
> kann mir jemand ein entsprechendes Codebeispiel geben wie
> so ein Interface auszusehen hat. So dass ich aus irgend einer
> Form auf empfangene Daten zugreifen kann.
>
> Besten Dank!
>
> Uwe

Wo ist genau das Problem?
Jede Form kann sich für den DataReceived-Event registrieren und 
entsprechend reagieren bzw. nicht reagieren wenn sie nicht aktiv ist 
(Form.ActiveForm). Genauso gut könnte man das gesamte Handling (Senden, 
Empfangen, Aufbereiten) in die Serial-Klasse packen, die dann einen 
neuen Event bereitstellt...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.