comunicarse o acceder a un padre desde otro usando c #

Parece que tengo muchos problemas con un problema simple. Sí, soy nuevo en c # pero trato de aprender lo que puedo sin saltar para publicar una pregunta. En este caso, creo que no estoy haciendo la pregunta correcta.

No hay ejemplos de código que ayuden aquí porque estoy hablando de los conceptos básicos (implementación). Todavía no he codificado nada, solo use el generador visual para crear mis formularios y menús de Windows.

El problema que tengo es cuando selecciono un elemento del menú (llámelo: establecer rutas) Quiero que la vista de la lista en mi formulario principal se cargue desde la ruta seleccionada cuando presiono OK en form2. Así que hice un simple cuadro de diálogo para encontrar la carpeta y tengo mi nueva ruta almacenada en form2 en un cuadro de texto. Cuando haga clic en Aceptar en ese formulario2 quiero que se rellene mi vista de lista formulario1. Sé cómo hacer todo esto, pero no puedo por mi vida acceder a form1 desde form2 o viceversa.

Intenté realizar una función de callback, pero no se puede hacer referencia a esa variable no estática … error porque mi formulario 1 es estático, por lo que no puedo crear ningún método no estático. Busqué en EventArgs, pero eso parece una matanza excesiva para una solicitud tan común.

Entonces, ¿cuál es la forma general de hacer esto?

La respuesta de Robert es correcta en cuanto a acceder a los miembros en otro formulario. Sin embargo, en general, debe almacenar el estado de su aplicación (llámelo “modelo”) por separado del estado de su interfaz de usuario (llámelo “vista”). Esto se vuelve muy importante a medida que su aplicación crece más allá de una o dos interacciones. Hay varias filosofías o patrones sobre cómo unir los dos (Google “model-view-controller” (MVC) y “model-view-viewmodel” (MVVM) por ejemplo), y si realmente desea hacerlo correctamente, Recomendaría aprender sobre eso. Mi preferencia es para el enfoque de MVVM, y puede hacerlo con bastante facilidad con Windows Forms, aunque fue diseñado teniendo en cuenta las aplicaciones WPF.

En .NET, la parte básica de código que debe usar para implementar la conexión entre su modelo de vista y su vista es una interfaz llamada INotifyPropertyChanged . Crea una clase que implementa esta interfaz y envía notificaciones cada vez que cambia una propiedad, por lo que, por ejemplo, para su propiedad de ruta, crearía esta clase:

class ViewModel : INotifyPropertyChanged { private string path; public string Path { get { return path; } set { if (value != path) { path = value; NotifyPropertyChanged(); } } } // This event gets triggered whenever a property changes. public event PropertyChangedEventHandler PropertyChanged; // This will cause the event to actually be triggered. It automatically determines the name of the property that triggered it using the [CallerMemberName] attribute - just a bit of .NET 4.5 sweetness. :) private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } 

Puede parecer mucho trabajo, pero ahora en su form1 puede crear una nueva instancia de “ViewModel”, suscribirse al evento y luego pasar la instancia a form2. form2 simplemente actualiza la propiedad Ruta en la instancia de viewmodel cada vez que el usuario selecciona una ruta diferente.

Entonces, Form1 necesita este código cerca de la parte superior:

 private ViewModel viewmodel = new ViewModel(); 

Y esto va en el constructor Form1:

 viewmodel.PropertyChanged += new EventHandler(OnPathChanged); 

Y al crear / mostrar form2:

 var form2 = new Form2(viewmodel); // Note, the viewmodel instance is being passed to the form2 constructor form2.Show(); 

El constructor de form2 almacena su propia referencia a la instancia “viewmodel” y establece la propiedad Path cuando el usuario cambia la ruta.

 private ViewModel viewmodel; public Form2(ViewModel viewmodel) { this.viewmodel = viewmodel; ... // Other stuff to set up your controls etc. goes here } private void PathChanged(object sender, EventArgs e) // This may be named differently in your code; it's the event handler that gets called when the path changes { // This will automatically notify the event handler in Form1! It's super-elegant and flexible. this.viewmodel.Path = txtPath.Text; // Assuming you have a textbox called txtPath } 

Y finalmente el controlador de eventos en Form1:

 private void OnPathChanged(object sender, EventArgs e) { var newPath = viewmodel.Path; // Get the updated path back from the viewmodel //TODO: Whatever you want to do when the path changes. } 

Aquí hay un enlace a una introducción MVVM realmente buena que usa formularios de Windows, usa dos formularios como los que tiene en su ejemplo. MVVM (Model-View-ViewModel) Pattern para aplicaciones de Windows Form, usando C #

Si necesita acceder a algo en otro formulario, simplemente mantenga una referencia a él desde su primer formulario, como esto:

 form2 = new Form2(); form2.Show(); form2.WhateverYouWantToAccess 

Dicho esto, si solo desea obtener una ruta de archivo del usuario, desea utilizar la clase OpenFileDialog .

 private void button1_Click(object sender, System.EventArgs e) { Stream myStream = null; OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.InitialDirectory = "c:\\" ; openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ; openFileDialog1.FilterIndex = 2 ; openFileDialog1.RestoreDirectory = true ; if(openFileDialog1.ShowDialog() == DialogResult.OK) { try { if ((myStream = openFileDialog1.OpenFile()) != null) { using (myStream) { // Insert code to read the stream here. } } } catch (Exception ex) { MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); } } }