Laden...

Wertübergabe an 2. Form

Erstellt von King-Malkav vor 15 Jahren Letzter Beitrag vor 15 Jahren 6.511 Views
King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren
Wertübergabe an 2. Form

Hallo Community,

ich habe ein kleines Problem. Ich habe eine Anwendung, bestehend aus 2 Forms und ich gebe beim Aufruf des 2. Forms (durch das erste) einen Wert über eine zusätzliche klasse mit. Das 2. Form wird einmal Global instanziert und beim schließen nur versteckt mit .hide(). Jetzt habe ich aber ein Problem, immer wenn sich der Übergebene Wert ändert, soll das 2. Form seinen inhalt neu laden. Ich habe da an ein Event in der zusätzlichen Klasse gedacht, was das 2. Form abonniert. Leider bekomme ich das nicht hin.

Hier mal den Code der zusätzlichen Klasse...


using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

// Statische Öffentliche Klasse um Werte ohne Instanzierung zu Übergeben
namespace ccpStoer
{
    public class uebergabe
    {
        private static String IDNR;
        
        public static String _IDNR
        {
            set
            {
                IDNR = value;
            }
            get
            {
                return IDNR;
            }
        }

        

    }
}

Gut wäre es jetzt, wenn ich beim set das Event feuere und das dann Form2 seinen inhalt neu läd. Hat jemand einen Tipp für mich?

Danke im Vorraus.

MFG

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren

Danke, aber die Themen habe ich auch schon durch...

Ich habe die klasse umgeschrieben, aber das Event wird scheinbar nicht gefeuert...


    public class uebergabe
    {
        private static String IDNR;
        public event EventHandler IDNRChanged;
        
        public static String _IDNR
        {
            
            get
            {
                return IDNR;
            }
        }

        public void setIDNR(string myID)
        {
            IDNR = myID;
            OnIDNRChanged(EventArgs.Empty);
        }

       

        protected virtual void OnIDNRChanged(EventArgs e)
        {
            EventHandler myEvent = IDNRChanged;
            if (myEvent != null)
            {
                myEvent(this, e);
            }
        }

        

    }
}

Die Werte werden korrekt an das zweite Form übergeben.
Werte ändere ich über Folgenden Aufruf aus Form1:


myUebergabe.setIDNR(lb_stoerung.SelectedValue.ToString());

Auf Form2 habe ich Folgenden Code...



 public Log()
        {
            InitializeComponent();
            uebergabe myuebergabe = new uebergabe();
            myuebergabe.IDNRChanged += new EventHandler(myuebergabe_IDNRChanged);
            
            
        }

void myuebergabe_IDNRChanged(object sender, EventArgs e)
        {
            MessageBox.Show(uebergabe._IDNR);
        }

Ich steh grad voll auf dem Schlauch...

MFG

4.931 Beiträge seit 2008
vor 15 Jahren

Du hängst das Event ja auch an eine lokale Variable:

uebergabe myuebergabe = new uebergabe();
myuebergabe.IDNRChanged += new EventHandler(myuebergabe_IDNRChanged);

du mußt schon den Event-Handler an das richtige Objekt hängen oder aber alternativ das Event auch statisch machen!

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren

Hi,

danke. Jetzt Funktioniert es. Ob es der beste weg ist, weiß ich aber nicht. Vielleicht kann ja ein "Experte" noch was dazu sagen.


using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

// Statische Öffentliche Klasse um Werte ohne Instanzierung zu Übergeben
namespace ccpStoer
{
    public class uebergabe
    {
        private static String IDNR;
        private static String NAME;
        public static event EventHandler IDNRChanged;
        
        public static String _IDNR
        {
            get
            {
                return IDNR;
            }
        }


        public static String _NAME
        {
            get
            {
                return NAME;
            }
            set
            {
                NAME = value;
            }
        }

        

        public void setIDNR(string myID)
        {
            IDNR = myID;
            OnIDNRChanged(EventArgs.Empty);
        }

        protected static void OnIDNRChanged(EventArgs e)
        {
            EventHandler myEvent = IDNRChanged;
            if (myEvent != null)
            {
                myEvent(IDNRChanged, e);
            }
        }

        

    }

 
}

Danke.

MFG

F
10.010 Beiträge seit 2004
vor 15 Jahren

// Statische Öffentliche Klasse um Werte ohne Instanzierung zu Übergeben

Sagt eigentlich schon alles.
Das ist eine Vorgehensweise, die niemals gemacht werden sollte.
Das wiederspricht so ziemlich jedem modernen Programmiergedanken.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren

// Statische Öffentliche Klasse um Werte ohne Instanzierung zu Übergeben
Sagt eigentlich schon alles.
Das ist eine Vorgehensweise, die niemals gemacht werden sollte.
Das wiederspricht so ziemlich jedem modernen Programmiergedanken.

Hast du einen Vorschlag wie ich es besser machen kann. Hab die Verlinkten Threads gelesen, da wird aber immer nur darauf hingewiesen das die Forms nicht abhängig von einander sein sollen und das sind sie ja schließlich nicht und kennen tun sich Form1 und 2 auch nicht.

MFG

F
10.010 Beiträge seit 2004
vor 15 Jahren

Das hast Du dann falsch interpretiert.
Es sollen sich nicht beide gegenseitig kennen.

Die aufrufende Klasse kennt natürlich das festgelegte öffentliche Interface der aufgerufenen Klasse.

D.h. deine Form1, erzeugt eine Form2 und kann parameter Übergeben, oder
sich an Events der Form2 hängen.
Form2 aber darf Form1 nicht kennen, und darf nur über die eigenen Parameter
oder die eigenen Events antworten.

Wenn deine Form2 über die Änderungen eines Parameters informiert werden
soll, kannst Du das über Parameterklassen machen, die INotifyPropertyChanged
implementieren.

Nur in 99% der Fälle ist das was Du da beschreibst eine suboptimale vorgehensweise.
Warum meinst Du das so machen zu müssen, bzw. was soll das ergeben.
Meist gibt es da bessere Lösungen für.

1.665 Beiträge seit 2006
vor 15 Jahren

Wenn deine 2. Form nur einmal pro Laufzeit instanziiert wird, dann kannst du diese über einen Service oder ähnlichem in deiner Anwendung verfügbar machen. Dieser Service kapselt die Logik und kann auch beispielsweise Wertänderungen vornehmen.

// Form1
{
    SpecialWindowService svc;
    svc.Show();

    ...

    // Wertübergabe an deine 2. Form
    svc.ChangeBackColor(Color.Cyan);
}

Das wäre ein Ansatz von enigen anderen.

Allerdings stellt sich mir die Frage, was du genau vorhast, dass du Werte aus Form1 in Form2 übergeben musst/willst.

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren

Hi,

danke für die Antwort.

Also ich habe in Form1 eine Listbox mit Werten aus einer DB, wenn diese doppelt geklickt werden, soll sich Form 2 öffnen und in einem Tab vorhandene Protokolleinträge aus der DB anzeigen, bzw. sollen sich hinzufügen lassen.

Mein Problem war/ist, dass ich die ID des Objekts aus der Listbox benötige um die Protokolle aus der DB nachzuladen. Wichtig dabei ist, dass Form1 weiter bedienbar bleibt und durch ein Doppelklick auf ein weiteres Objekt aus der Listbox in Form2 ein weiterer Tab geöffnet wird und dort auch die entsprechenden Protokolle nachgeladen werden. Deshalb hab ich mir auch den Event geschrieben, damit Form2 selbstständig die neuen Werte laden kann und gegebenenfalls einen Tab erstellt. Das ganze soll so ähnlich aussehen wie ICQ, also vom Prinzip her.

Das 2. Form wird auch nie wirklich geschlossen, sondern nur wieder mit hide() "versteckt", damit die Daten nicht nachgeladen werden müssen. Ist eine Singleuser Anwendung.
MFG

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren
  
    // Wertübergabe an deine 2. Form  
    svc.ChangeBackColor(Color.Cyan);  
}  

Ist das eigentlich nicht genau das was man vermeiden soll?

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo King-Malkav,

du musst, wie FZelle schon weiter oben sagte, die Richtung unterscheiden.

Form2 sollte Form1 nicht kennen.

Form1 kennt aber Form2 und das ist auch ok. Und deshalb ist es auch ok, wenn Form1 auch zu einem späteren Zeitpunkt auf Form2 zugreift.

herbivore

1.665 Beiträge seit 2006
vor 15 Jahren

Ist das eigentlich nicht genau das was man vermeiden soll?

Kommt darauf an. Hier missbrauchst du immerhin nicht ein statisches Property zum Datentransfer.


// Form1
{
    // Doppelklick ListBox Eintrag -->

    // Zeigt in Form2 in einem neuen Tab die Protokolle
    // zum geklickten Item
    svc.ShowProtocol(itemId);
}
// SpecialWindowService
public void ShowProtocol(Guid itemId)
{
    // Lade Protokolle aus DB
    // Erstelle Tab
    // Daten anzeigen
}
King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren

Hallo herbivore,

danke ich glaube jetzt habe ich es verstanden. Also rufe ich mein Form2 mit Parameter aus Form1 auf und greife auf ein public Event aus Form2 zu, damit er die Daten aktualisiert. Habe ich das jetzt richtig verstanden?

Das OnLoad Event des Forms kann ich ja nicht nutzen, da es ja nur einmal geladen wird. Es gibt ja auch nur eine Instanz davon.

MFG

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo King-Malkav,

obwohl ich gerade noch mal alles von dir gelesen habe, weiß ich leider nicht genau, was du machen willst.

Was ich verstanden habe: Form1 erzeugt Form2. Form2 gibt es nur einmal.

Aber welche Änderungen oder Benutzeraktionen in welchem Fenster sollen wo Auswirkungen haben? Und was spielt das einmal von Form1 an Form2 übergebene Objekt für eine Rolle?

herbivore

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren

Hi herbivore,

Form1 hat eine Liste mit Daten aus der Datenbank. Diese haben eine Bezeichnung und eine ID. Die Bezeichnung ist der text des ListControls und die ID ist der Value.

Form2 Ist ein Fenster mit einem Tabcontrol und soll es nur einmal geben. Wenn ich jetzt in meinem ListControl einen Eintrag auswähle, werden mir in Form1 noch Details zu dem Objekt angezeigt. Bei einem Doppelklick auf das Objekt soll sich Form2 öffnen, ein neuer Tab erstellt werden (auser es ist schon einer für das Objekt vorhanden) und dann sollen Protokolldaten aus der Datenbank gelesen werden und in einem Label auf dem Tab in Form2 angezeigt werden. Damit ich in der DB das richtige Protokoll finde, benötige ich die ID aus Form1.
Wird jetzt in Form1 ein anderes Objekt in der Liste doppelt geklickt wird ein neuer Tab erstellt und dann für dieses Objekt die Protokolldaten nachgeladen.

Mit meiner Lösung klappt das ganz gut, aber wenn ich mir die Statische Klasse sparen kann, ist das besser.

Am Montag kann ich auch ein paar Screenshots posten, dann wird es vielleicht klarer.

MFG

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo King-Malkav,

ich denke, jetzt ist es mir klar geworden. Da brauchst du an keiner Stelle Events, weil der Informationsfluss nur innerhalb von Form1 läuft sowie von Form1 zu Form2. Und Form1 darf ja Form2 kennen und kennt es auch. Das heißt, du kannst es so machen, wie JunkyXL vorgeschlagen hat. Direkte Übergabe des Werts. Hier der Code etwas abgewandelt:


// Form1

private Form2 _form2;

public Form1 ()
{
    _form2 = new Form2 ();
    _form2.Show ();
}

private void Object_DoubleClick (...)
{
    // Wertübergabe an deine 2. Form
    _form2.ShowProtocol(itemId);
}

herbivore

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren

Hallo herbivore,

danke ich werde mal am Montag testen und Berichten.

MFG

King-Malkav Themenstarter:in
264 Beiträge seit 2006
vor 15 Jahren

So nochmal danke für die Hilfe, hat ohne Probleme und mit weniger Code funktioniert.
Ich könnte mir an den Kopf fassen, dass ich die recht Simple Lösung nicht selbst gesehen habe.

Danke an alle nochmal.