Laden...

Von Form2 auf Form1 zugreifen [die Richtung d. Zugriffs ist schlecht/unnötig; hier d. Alternativen]

Erstellt von Adler vor 19 Jahren Letzter Beitrag vor 17 Jahren 113.574 Views
Thema geschlossen
Information von herbivore vor 18 Jahren

Dies ist ein Thread, auf den aus der FAQ ([FAQ] Kommunikation von 2 Forms) verwiesen wird. Bitte keine weitere Diskussion, sondern nur wichtige Ergänzungen und diese bitte knapp und präzise. Vielen Dank!

A
Adler Themenstarter:in
47 Beiträge seit 2004
vor 19 Jahren
Von Form2 auf Form1 zugreifen [die Richtung d. Zugriffs ist schlecht/unnötig; hier d. Alternativen]

Hallo.

Ich habe hier höllische Probleme!

Ich habs schon mit allen Mitteln versucht die ich nun kenne, hilft nichts.
versuche auf shtext (public variable von Form1) zuzugreifen.
Und das von Form2 aus.

        myForm1.shtext = textBox1.Text;  

So, er kennt shtext nicht, myForm1 ist public in Form1 deklariert und ich habe das this von Form1 darauf gesetzt.

Allerdings findet er ja myForm1, aber warum dann shtext net?!
mit Parent einfach gehts auch net.

wäre lieb wenn mir jemand helfen könnte.

MfG Meine wenigkeit.
381 Beiträge seit 2004
vor 19 Jahren

Du hast zwei Formulare:

Form1
Form2

In Form1 nöchtest du auf eine Variable von Form2 zugreifen:


private void GetVauleFromForm2()
{
  Form2 frm2 = new Form2();
  MessageBox.Show( frm2.Variable );
}

public class Form2 : System.Windows.Forms.Form
{
  public string variable;

  public Form2()
  {
    this.variable = "Rene Paschold";
  }
}

Sollte funktionieren. Sind den bei dir die beiden Forms in der gleichen Assembly? Schon mal versucht über Properties zu gehen?

Mit freundlichen Grüßen

René Paschold
.NET Developer / Trainer / Speaker / Author /
Projectleader / Software-Architect


.blog http://www.rene-paschold.de/
.business http://www.smarthouse.de/

N
4.644 Beiträge seit 2004
vor 19 Jahren

Ich habs schon mit allen Mitteln versucht die ich nun kenne, [...]

Kennst Du die Forumsuche? 😉

A
Adler Themenstarter:in
47 Beiträge seit 2004
vor 19 Jahren

^Ja die Forensuche kenne ich.

Mh, also ich möchte von Form2 die von Form1 erstellt ist auf Form1 zugreifen.
Schreiben und Lesen, allerdings bekomm ich die variable net.
Und das kann irgendwie net sein.
Da ich ja in Form2 Form1 deklariert habe und in Form1 diese Variable mit this belegt habe.

Eben drum versteh ichs net.

MfG Meine wenigkeit.
381 Beiträge seit 2004
vor 19 Jahren

Achso, du willst das andersrum machen 🙂 Ich hatte verstanden das du von Form1 auf Form2 zugreifen willst. Entweder per Reflection oder noch einfach du übergibst an Form2 das Object von Form1:

In Form1:


private void button2_Click(object sender, System.EventArgs e)
{
	Form2 frm = new Form2();
	frm.frm1 = this;
	frm.ShowDialog();
}

Und in Form2:


private Form1 _frm1;

public Form1 frm1
{
	set { this._frm1 = value; }
}

private void button1_Click(object sender, System.EventArgs e)
{
	MessageBox.Show(
		this._frm1.vorname
		);
}

Das ist der einfachste Weg. Über Reflection mit typeof würde es auch gehen, hängt davon ab in was für einem Umfang du das ganze programmieren möchtest.

Information von herbivore vor 10 Jahren

So sollte man das nie machen. Form2 sollte Form1 überhaupt nicht kennen. Es reicht immer, wenn Form1 Form2 kennt. Wenn Form2 mit Form1 "sprechen" will, kann es dafür (eigene) Events feuern und Form1 kann sie abonnieren.

Mit freundlichen Grüßen

René Paschold
.NET Developer / Trainer / Speaker / Author /
Projectleader / Software-Architect


.blog http://www.rene-paschold.de/
.business http://www.smarthouse.de/

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo Adler,

für den Zugriff zwischen Formularen, gibt es schon eine Menge Threads. Die Forumssuche nach Form1 Form2 hilft. Wenn du es im oo Sinne richtig machen willst, such noch besser nach Observer.

herbivore

1.696 Beiträge seit 2006
vor 18 Jahren
Sorry

Hi Leute,

sorry, dass ich den Thread ausgrabe, aber bitte hilft einen Newbie 😦, denn ich bin am Ende mit meinem Alphabet.

ich habe in Form1

 
...
public string var;


wenn ich den String in Form1() initialisiere und bei einem Event den Wert ändere, erhalte ich den Init-Wert, wenn ich von Form2 darauf zugreife. Warum ?(


// in Form1

public Form1()
{
   this.var = "test";
}

		private void dataGrid1_CurrentCellChanged(object sender, System.EventArgs e)
		{
			if (dataGrid1[dataGrid1.CurrentCell] != System.DBNull.Value)
			{
				MessageBox.Show ("Col is " + dataGrid1.CurrentCell.ColumnNumber
					+ ", Row is " + dataGrid1.CurrentCell.RowNumber 
					+ ", Value is " + dataGrid1[dataGrid1.CurrentCell] );
				this.var = dataGrid1[dataGrid1.CurrentCell].ToString();
                            // hier ist var = "blabla"
				Form2 frm2 = new Form2();
				frm2.Show();
			}
		}

...


// Form2

public void Form2_Load(...)
{
   Form1 frm1 = new Form1();
   MessageBox(frm1.var); // hier wird aber "test" angezeigt
}
...
 

Hilfe, was mache ich falsch?

Vielen Dank im voraus.

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

4.221 Beiträge seit 2005
vor 18 Jahren

Hilfe, was mache ich falsch?

Alles 8)

public string var ist schlecht, da eine Klasse keine public Fields (Variablen) haben sollte. Die Variable bleibt private PUNKT... der Zugriff auf die Variable geschieht über Properties (das Property ist dann public). Zudem willst du var ja in Form 2 anzeigen... also muss es auch auf Form2 deklariert sein.

Du erstellst also auf Form2:


//Die Variable
private string _TextToShow;

//das Property
public string TextToShow
{
   get{return this._TextToShow;}
   set{this._TextToShow=value;}
}

im Form_Load oder wo auch immer kannst Du dann die MessageBox mit dem Text von this._TextToShow ausgebne.

//so und auf Form1 machst Du wie bisher auch 

Form2 frm2=new Form2();
frm2.TextToShow=dataGrid1[dataGrid1.CurrentCell].ToString();
frm2.Show();



wobei das erstellen von Form2 innerhalb dieses Events ja nicht wirklich Sinn macht...

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

1.696 Beiträge seit 2006
vor 18 Jahren

vielen vielen Dank,

wobei das erstellen von Form2 innerhalb dieses Events ja nicht wirklich Sinn macht...

wie dann? in einer Funktion reinpacken und im Event_Funktion diese Funktion aufrufen? Ich muss auf ein weiteres Fenster zur Bearbeitung des ausgewählten Datensatz öffnen.

Gruß

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo vbprogger,

du solltest nur eine Instanz von Form1 erzeugen und diese erstellt eine Instanz von Form2. Wenn du in Form2 nochmal ein Form1-Objekt erstellen würdest, hättest du drei Fenster auf dem Schirm und das zweite Form1 wäre ein anderes Objekt als das erste Form1.

Form2 muss und sollte sowieso nicht auf Form1 zugreifen. Stattdessen registriert sich Form1 einfach für das Closing oder Closed-Event von Form2 und kann in dem entsprechenden EventHandler alle Werte aus Form2 auslesen - über entsprechenden Properties, die du in Form2 zur Verfügung stellen musst.

Statt dass Form2 die Ergebnisse zu Form1 schiebt, holt also als Form1 die Ergebnisse bei Form2 ab.

Also nochmal Form2 sollte nie auf Form1 zugreiffen, ja am besten nicht einmal wissen, dass es die Klasse Form1 gibt.

herbivore

85 Beiträge seit 2006
vor 18 Jahren

Hier mal der code wie ich es in VB.Net machen. Müßt ihr halt nur noch übersetzten:


Public Shared instForm2 as Form2

Public Sub New()
   instForm2 = Me
End Sub

und wenn ich jetzt von Form1 auf funktionen oder objekte von Form2 zgreifen will geht das sehr einfach


Form2.instForm2.Objekt.Eigenschaft = Wert

sollte nicht schwer in C# zu übersetzten sein.

gruß floyd

"...denn wir arbeiten nicht nur um uns selbst zu verbessern, sondern auch den Rest der Menschheit!"

blog.freakfabrik.net

563 Beiträge seit 2004
vor 18 Jahren

Hi Floyd

Die Forminstanz statisch zu deklarieren halte ich für eine sehr schlechte Lösung. Das ist vieleicht bequem, aber nicht im Sinne von OO.

Vor allem Anfängern sollte man von Anfang an zeigen, wie man sowas richtig macht.

Gruss,
.unreal

85 Beiträge seit 2006
vor 18 Jahren

Hmm mag ja sein aber was spricht dagegen? Nur so aus neugier.

Gruß Floyd

"...denn wir arbeiten nicht nur um uns selbst zu verbessern, sondern auch den Rest der Menschheit!"

blog.freakfabrik.net

2.082 Beiträge seit 2005
vor 18 Jahren

Ein anderer Vorschlag wäre auch, dass du deine var beim erstellen vom Form2 mit übergibst. Also im Konstruktor von Form2 als parameter.

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

4.221 Beiträge seit 2005
vor 18 Jahren

Hmm mag ja sein aber was spricht dagegen? Nur so aus neugier.

Es ist eine völlig unnötige Cross-Reference... zudem entsteht eine unnötige Koppelung.... und was noch hässlicher ist, eine Koppelung über eine static-Variable 🙄

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

1.696 Beiträge seit 2006
vor 18 Jahren

Vielen Dank an alle, das muss ich erstmal noch verdauen und versuchen umzusetzen. Ich hoffe, dass ich Euch nicht weiter hiermit belästige, sollte es doch der Fall sein, so hoffe ich, dass Ihr doch gnädig seid und mir Eure Hilfe weiterhin anbietet.

Viele Grüße
vbprogger

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

4.221 Beiträge seit 2005
vor 18 Jahren

so hoffe ich, dass Ihr doch gnädig seid und mir Eure Hilfe weiterhin anbietet.

Wir versuchen immer zu helfen..... vorallem wollen wir dir helfen zu PROGRAMMIEREN.... BASTELN kannst Du ja selber.... daher auch die Kritiken

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

2.082 Beiträge seit 2005
vor 18 Jahren

Schließlich hat jeder Programmierer irgenwie in Art und Weise einen eigenen Stil. Das ist ja gerade das schöne an dem Beruf.

Wir geben lediglich nur Tipps, wies besser performant wird oder sicherer.

Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Floyd,

ich wollte nur noch mal bekräftigen, was Programmierhans schon schrieb. Hier eine static Variable zu verwenden, ist wirklich richtig schlecht. Sollte man auf keinen Fall so machen.

Wie ich oben schon sehr nachdrücklich schrieb, sollte Form2 nicht mal die Klasse Form1 kennen.

herbivore

1.696 Beiträge seit 2006
vor 18 Jahren

Hallo,

ich bin echt zu blöd für .NET, bitte hilft mir, am besten mit etwas Pseudo-Code.

Wie mein Nick scho aussagt, progge ich bisher in VB, und dort kann ich Form.visible = true/false setzen, währen in in einer anderen Form die Daten bearbeite, kehre ich zurück, habe ich immer noch den Zustand, bevor ich die Form verlasse, mit allen bisher gesetzt-/gerechneten Werte.

Wie mache ich das in .NET?

Ich habe versucht, das was Ihr vorgeschlagen habt umzusetzen, etwa so


// Form1
...
private string var1;
private string var2;
...
private System.Windows.Forms.DataGrid dataGrid1;
...

public string myVar1
{
   get{...}
   set{...}
}

// dito für var2

private void irgendwas_click(...)
{
   Form2 frm2 = new Form2(this.something);
   frm2.Show();
}

//--------------------//

// Form2

...
public Form2 (string argVar)
{
    this.var = argVar
}
...
// Close_event
private void Form2_Close(object sender, System.EventArgs e)
{
   // wie gebe ich Daten an Form3 zurück und Form3 reaktivieren (focus()?)
   // wenn ich:
   Form3 frm3 = new Form3();
   frm3.myVar1 = this.bla1;
   frm3.myVar2 = this.bla2;
   frm3.Focus();
   // mache, dann verliere ich die bisherige Daten, z.B. das DataGrid ist leer
}

Bitte hilfe mir. Wie macht man sowas, dass alle Daten trotz Hinundher-Springerei erhalten bleiben.

Es geht erstmal darum, dass ich 2 DataGrid in Form1 habe, klicke ich auf einen Datensatz in Grid1, werden noch weitere Daten anhand der ID rausgeholt und in Form2 dargestellt. In Form2 schau sich der User die Daten an und entscheidet, ob er den DS übernimmt oder nicht, dabei wird Form2 wieder geschlossen und seine Entscheidung an Form1 übergibt, was entscheiden soll, ob der DS in Grid2 geschoben wird oder nicht. Das macht der User solange, bis er genug hat und das Ergebnis dann abspeichert. Warum in die 2. Form? Weil es u.U. auch Bilder/Scan von Datenblättern, so dass alles in einer Form nicht möglich ist.

Vielen Dank für Eure Bemühungen.

Gruß

P.S. ich will mir das Buch Windows Programmierung mit C# von Charles Petzold kaufen http://www.amazon.de/exec/obidos/ASIN/3860636529/qid=1137529961/sr=2-1/ref=sr_2_3_1/028-8399012-0766930 . Ist das Buch gut/empfehlenswert?

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Charles Petzold,

Form.Visible ist ja eine .NET-Property. Die gibt es ist VB.NET genauso wie in C#. Es gibt auch Form.Show () und Form.Hide ().

Charles Petzold ist auf jeden Fall mal einer der, wenn nicht sogar der Guru für Windows-Programmierung.

herbivore

4.221 Beiträge seit 2005
vor 18 Jahren

Schau Dir mal das Beispiel an...




using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication3
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.TextBox txtAufForm1;
		private System.Windows.Forms.Button btnForm2Normal;
		private System.Windows.Forms.Button btnForm2Modal;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.txtAufForm1 = new System.Windows.Forms.TextBox();
			this.btnForm2Normal = new System.Windows.Forms.Button();
			this.btnForm2Modal = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// txtAufForm1
			// 
			this.txtAufForm1.Location = new System.Drawing.Point(96, 40);
			this.txtAufForm1.Name = "txtAufForm1";
			this.txtAufForm1.Size = new System.Drawing.Size(136, 20);
			this.txtAufForm1.TabIndex = 0;
			this.txtAufForm1.Text = "";
			// 
			// btnForm2Normal
			// 
			this.btnForm2Normal.Location = new System.Drawing.Point(96, 80);
			this.btnForm2Normal.Name = "btnForm2Normal";
			this.btnForm2Normal.Size = new System.Drawing.Size(136, 23);
			this.btnForm2Normal.TabIndex = 1;
			this.btnForm2Normal.Text = "Form2 Normal";
			this.btnForm2Normal.Click += new System.EventHandler(this.btnForm2Normal_Click);
			// 
			// btnForm2Modal
			// 
			this.btnForm2Modal.Location = new System.Drawing.Point(96, 115);
			this.btnForm2Modal.Name = "btnForm2Modal";
			this.btnForm2Modal.Size = new System.Drawing.Size(136, 23);
			this.btnForm2Modal.TabIndex = 2;
			this.btnForm2Modal.Text = "Form2 Modal";
			this.btnForm2Modal.Click += new System.EventHandler(this.btnForm2Modal_Click);
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(328, 221);
			this.Controls.Add(this.btnForm2Modal);
			this.Controls.Add(this.btnForm2Normal);
			this.Controls.Add(this.txtAufForm1);
			this.Name = "Form1";
			this.Text = "Form1";
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		private void btnForm2Normal_Click(object sender, System.EventArgs e)
		{
			Form2 frm=new Form2();
			frm.TextImTextBoxAufForm2=this.txtAufForm1.Text;
			frm.Closed+=new EventHandler(frm_Closed);
			frm.Show();
		}

		

		private void btnForm2Modal_Click(object sender, System.EventArgs e)
		{
			Form2 frm=new Form2();
			frm.TextImTextBoxAufForm2=this.txtAufForm1.Text;
			if (frm.ShowDialog()==DialogResult.OK)
			{
				this.txtAufForm1.Text=frm.TextImTextBoxAufForm2;
			}
		}

		private void frm_Closed(object sender, EventArgs e)
		{
			Form2 frm=sender as Form2;
			if (frm!=null) 
			{
				if (frm.DialogResult==DialogResult.OK)
				{
					this.txtAufForm1.Text=frm.TextImTextBoxAufForm2;
				}
				frm.Closed-=new EventHandler(frm_Closed);
			}
		}
	}
}






using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace WindowsApplication3
{
	/// <summary>
	/// Summary description for Form2.
	/// </summary>
	public class Form2 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.TextBox txtAufForm2;
		private System.Windows.Forms.Button btnOK;
		private System.Windows.Forms.Button btnCancel;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form2()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.txtAufForm2 = new System.Windows.Forms.TextBox();
			this.btnOK = new System.Windows.Forms.Button();
			this.btnCancel = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// txtAufForm2
			// 
			this.txtAufForm2.Location = new System.Drawing.Point(56, 40);
			this.txtAufForm2.Name = "txtAufForm2";
			this.txtAufForm2.TabIndex = 0;
			this.txtAufForm2.Text = "";
			// 
			// btnOK
			// 
			this.btnOK.Location = new System.Drawing.Point(88, 128);
			this.btnOK.Name = "btnOK";
			this.btnOK.TabIndex = 1;
			this.btnOK.Text = "OK";
			this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
			// 
			// btnCancel
			// 
			this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
			this.btnCancel.Location = new System.Drawing.Point(176, 128);
			this.btnCancel.Name = "btnCancel";
			this.btnCancel.TabIndex = 2;
			this.btnCancel.Text = "Cancel";
			this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
			// 
			// Form2
			// 
			this.AcceptButton = this.btnOK;
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.CancelButton = this.btnCancel;
			this.ClientSize = new System.Drawing.Size(272, 165);
			this.Controls.Add(this.btnCancel);
			this.Controls.Add(this.btnOK);
			this.Controls.Add(this.txtAufForm2);
			this.Name = "Form2";
			this.Text = "Form2";
			this.ResumeLayout(false);

		}
		#endregion

		private void btnOK_Click(object sender, System.EventArgs e)
		{
			this.DialogResult=DialogResult.OK;
			this.Close();
		}

		private void btnCancel_Click(object sender, System.EventArgs e)
		{
			this.DialogResult=DialogResult.Cancel;
			this.Close();
		}

		
	
		public string TextImTextBoxAufForm2
		{
			get{return this.txtAufForm2.Text;}
			set{this.txtAufForm2.Text=value;}
		}
	}
}


Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

1.696 Beiträge seit 2006
vor 18 Jahren

vielen Dank Programmierhans, du hast mir wirklich Augen geöffnet. Ich habe das Buch soeben bestellt und hoffe, dass ich Euch nicht mehr mit diesem Anfängerproblem belästigen werde.

Gruß

Ich bin verantwortlich für das, was ich sage, nicht für das, was du verstehst.

**:::

V
3 Beiträge seit 2006
vor 17 Jahren

@Rene Paschold

Hallo!

Könntest du dazu ein Tutorial schreiben und das genauer erklären?
danke

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo virt3791,

das hier ist das "Tutorial". Ansonsten Kommunikation von 2 Forms

herbivore

V
3 Beiträge seit 2006
vor 17 Jahren

Ja, aber etwas ausführender könnte man es schon machen.
Etwas mehr Kommentare, damit man es leichter versteht.

bitte........

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo virt3791,

öfter und breiter als dieses Thema wurde kein anderes diskutiert, noch ausfühlicher können wir es also kaum machen. Aber du könntest auch was tun: Etwas mehr lesen, damit du es leichter verstehst. Das Thema ist ohnehin mehr was für ein Buch als ein Forum.

Aber diese Diskussion hatten wir aber schon oft, deshalb => closed.

herbivore

Thema geschlossen