Entwickler-Ecke

WinForms - Klasse in mehreren Forms nutzen


c#ler - Mi 07.03.12 14:41
Titel: Klasse in mehreren Forms nutzen
Hallo,

Ich habe eine MessageQueue in meiner Startklasse ("Programm.cs")erstellt, deren Funktionen ich in 3 Forms nutzen möchte.
(Damit ich nur eine MessageQueue offen habe und nicht in jedem Formular eine öffnen muss)

Das Problem: Ich weiß nur leider nicht, wie ich meinen MessageQueue an die Forms übergebe.
Please help


Ich hatte mir das so in etwa gedacht, aber irgendwie hab ich nen denkfehler

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
//In Programm.cs

public class Programm
{
    MessageQueue _mq = new MessageQueue();

    public void Form1load()
    {
        Form1 Instance = new Form1(_mq);
    }
}

//in Form1
public partial class Form1 : Form
{
InitializeComponent();
//Aufruf der MessageQueue
}


Ralf Jansen - Mi 07.03.12 15:27

Zitat:
Ich hatte mir das so in etwa gedacht


Die Denkrichtung ist richtig. Aber aus halb wiedergegebenen Code kann man wohl kaum Fehler ableiten.

Program ist üblicherwiese eine statische Klasse insofern sollte darin auch alles als statisch markiert sein.
Hat deine Form1 auch einen entsprechenden Konstructor? Wer ruft wie Form1load() auf? Wer zeigt Instance an wenn Form1 eine lokale Variable ist und die Methode selbst es nicht tut?

Wenn das ganze eine Winforms Project ist würde ich empfehlen den Code nicht in Programm zu packen sondern das erzeugen und verwalten deine Klasse in die Hauptform deiner Anwendung zu verlegen und dann die MessageQueue Klasse so wie du schon gedacht hast an deine weiteren Subformen über deren Konstruktor weiterreichen.


c#ler - Mi 07.03.12 15:53

Vielen Dank schonmal dafür,
es ist leider nicht möglich Programm als static zu deklarieren, weil ich noch informationen aus einem Pluginprojekt darin einfließen lasse und dies sonst nicht möglich ist.
Der Konstruktor für Form1 lautet

C#-Quelltext
1:
2:
3:
4:
public Form1()
   {
      InitializeComponent();
   }


Das ist meine Programm.cs
Das X ersetzt Firmeninterne Daten
Der Aufruf der Form1 erfolgt im Programm.cs

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
namespace xx.Programm
{
    public class Programm : x.Plugins.BasePlugin
    {
        MessageQueue _mq = new MessageQueue();

        PluginMenuEntry _phoneButton = null;
        Form1 _frmPhone = null;

        public Programm()
            : base("'x.Plugin.Phone")
        {
        }

        void _phoneButton_Activated(object sender, EventArgs e)
        {
            Form1Load();
        }

        public override void Initialize(x.IPluginManager pluginManager)
        {
            _phoneButton = new PluginMenuEntry()
            {
                Name = "Phone",
                Icon = Properties.Resources.phone,
            };
            _phoneButton.Activated += new EventHandler(_phoneButton_Activated);
            ParentApplication.AddMenuEntry(_phoneButton);
        }
        public override void Uninitialize(IPluginManager pluginManager)
        {
        }

        public void Form1Load()
        {
            if (_frmPhone == null)
                // = quasi Instance
                _frmPhone = new Form1(_mq); //_mq kann ich leider nicht so einfach an Form1 übergeben
            _frmPhone.ShowDialog();
        }

        public override void Dispose()
        {
            if (_frmPhone != null)
            {
                _frmPhone.Close();
                _frmPhone.Dispose();
                _frmPhone = null;
            }
            base.Dispose();
        }
    }
}


Es ist ein WinForms Projekt für intelligente Geräte (WinCE)

Moderiert von user profile iconTh69: Full-Quote entfernt


Ralf Jansen - Mi 07.03.12 16:00

Oh Programm ist nicht die Program Klasse. Nicht sehr clevere Namenswahl, da muß man ja durcheinander kommen.

Zitat:
Es ist ein WinForms Projekt für intelligente Geräte (WinCE)


Auch eine völlig unerhebliche Info die man mal irgendwann hinterher werfen kann :motz:

Zitat:
_frmPhone = new Form1(_mq); //_mq kann ich leider nicht so einfach an Form1 übergeben


Doch wenn du Form1 auch einen entsprechenden Konstructor gibst den man so aufrufen kann.


c#ler - Do 08.03.12 10:40

Ich stell mich blöd an, dass weiß ich...aber ich mache und tue und es klappt nicht....

Ich habe:
In meiner Form1 einen Konstruktor MQ angelegt

C#-Quelltext
1:
2:
3:
public MQ()
        {
        }

In meiner Programm Klasse Achtung: nicht Program.cs ;-) habe ich die MessageQueue angelegt.

C#-Quelltext
1:
2:
3:
4:
public void MQ()
        {
            MessageQueue _messageQueue = new MessageQueue();
        }

Dann übergebe ich noch MQ an mein Formular

C#-Quelltext
1:
2:
3:
4:
5:
6:
public void ShowPhone()
        {
            if (_frmPhone == null)
            _frmPhone = new Form1(MQ);
            _frmPhone.ShowDialog();
        }

Irgendetwas mache ich falsch, aber ich bin nicht blickig.. Kann ich bitte nochmal Syntaxhilfe beantragen?

Moderiert von user profile iconTh69: Full-Quote entfernt.


lothi - Do 08.03.12 11:11

Hallo

Im Form1 der Konstruktor heisst Form1, kann man nicht ändern.
Wenn du MQ übergeben willst musst du eine Eigenschaft in Form1 erstellen.
Dann erstellst du einen neuen Konstruktor mit einem Parameter.

Musst dann noch gucken ob das Form1 nicht schon von der Main() Methode aufgerufen wird.

Gruss Lothi


c#ler - Do 08.03.12 11:26

user profile iconlothi hat folgendes geschrieben Zum zitierten Posting springen:

Musst dann noch gucken ob das Form1 nicht schon von der Main() Methode aufgerufen wird.

Da es zu Allgemeiner Verwirrung beiträgt benenne ich die Klasse jetzt mal um.
Sie hieß Programm.cs (nicht Program.cs)
ab sofort heißt die Klasse Phone.cs (Program.cs gibt es extra, aber nicht in diesem Projekt, sondern lediglich in dieser Projektmappe)

Ich muss eine Eigenschaft in Form1 erstellen um meine MessageQueue zu übergeben?
Das bedeutet ich gebe in Phone.cs an

C#-Quelltext
1:
2:
MessageQueue mq = new MessageQueue();
mq.GsmEnableAtCommands(true); //z.B.

und dann erstelle ich in meiner Form1:

C#-Quelltext
1:
2:
3:
4:
public Form1(mq.GsmEnableAtCommands(true))
{
InitializeComponent();
}


Ich habe da immernoch einen Denkfehler.
Tut mir leid, aber ich bin grad voll raus.

Moderiert von user profile iconTh69: Full-Quote entfernt


Ralf Jansen - Do 08.03.12 11:55

Zitat:
Ich habe da immernoch einen Denkfehler.


Ein Konstruktor ist einfach eine Methode ohne explizit angegeben Rückgabewerte. Man übergibt Parameter an eine Methode der man bei der Defintion als Typ-Name Paar angibt.
Du aber
Zitat:

C#-Quelltext
1:
public Form1(mq.GsmEnableAtCommands(true))                    


versuchst einfach in der Methodendefinition einen Methodenaufruf! Ausführbaren Code kannst du nur im Body einer Methode angeben in der Definition der Methode nur ... tada ... Definitionen.
Der Compiler sollte dir genau das auch gesagt haben.

Also eher


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
public class Form1 : Form
{
    private MessageQueue _messageQueue;

    public Form1(MessageQueue messageQueue) : this()
    {
        _messageQueue = messageQueue;
    }

    public Form1() // Diesen Konstruktor nicht mehr direkt benutzen. Dieser Konstruktor ist nur noch da damit der Winformsdesigner funktioniert.
    {   
        InitializeComponent();
    }

    public void MyLovelyDoSomethingWithTheMessageQueueMethod()
    {
        messageQueue
        // blah 
    }
}


Und dann halt im Aufrufer der Form die MessageQueue an den Konstruktor der Form übergeben. So wie man eben Methoden aufruft.


c#ler - Do 08.03.12 12:17

Jetzt verstehe ich. Vielen Dank, da wäre ich ja ewig nicht drauf gekommen.
Ich muss mir anscheinend malwieder ein wenig Basics anschauen. (Methodenaufruf / Klasseninstanzierung etc.) :(

Vielen Dank für die Hilfe! Gruss

Moderiert von user profile iconTh69: Full-Quote entfernt


Ralf Jansen - Do 08.03.12 12:27

Vielleicht in deinen Beiträgen demnächst nicht immer alles Quoten sondern etwas gezielter. Hier schreiben ja nicht soviele durcheinander das man sonst nicht weiß worauf sich dein Beitrag bezieht. Aber deine Beiträge sind so schwerer lesbar und schrecken potentielle Diskutanten ab.


Th69 - Do 08.03.12 13:17

Danke Ralf,

ich habe die Full-Quotes entfernt und eine PN an c#ler geschrieben.


lothi - Fr 09.03.12 15:55

user profile iconc#ler hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconlothi hat folgendes geschrieben Zum zitierten Posting springen:

Musst dann noch gucken ob das Form1 nicht schon von der Main() Methode aufgerufen wird.

Da es zu Allgemeiner Verwirrung beiträgt benenne ich die Klasse jetzt mal um.

Ne, ich war nicht verwirrt. :wink:
Es ist nur so, das wenn man ein WinForm-Projekt erstellt, das Form1 direkt in der Main() Methode aufgerufen wird.
Deine Form heisst nun mal Form1 und so wollte ich dir einen vorsorglichen Tip gegeben. :D

Gruss Lothi