2011-01-27 16 views
9

Tengo dos clases Form, una de las cuales tiene ListBox. Necesito un colocador para la propiedad SelectedIndex del ListBox, al que quiero llamar desde el segundo Form.¿Cómo acceder a un control de formulario para otro formulario?

En el momento que estoy haciendo lo siguiente:

Formulario 1

public int MyListBoxSelectedIndex 
{ 
    set { lsbMyList.SelectedIndex = value; } 
} 

Formulario 2

private ControlForm mainForm; // form 1 

public AddNewObjForm() 
{ 
    InitializeComponent(); 
    mainForm = new ControlForm();   
} 

public void SomeMethod() 
{ 
    mainForm.MyListBoxSelectedIndex = -1; 
} 

¿Es esta la mejor manera de hacer esto?

+0

[Interacción entre las formas -? Cómo cambiar un control de un formulario de otra forma] (https://stackoverflow.com/a/38769212/3110834) –

Respuesta

2

Suelo usar el patrón de diseño Singleton para algo como esto http://en.wikipedia.org/wiki/Singleton_pattern. Haré que la forma principal de ejecución de la aplicación sea singleton, y luego crearé accesos a formularios y controles que quiero tocar en otras áreas. Los otros formularios pueden obtener un puntero al control que desean modificar o los datos en la parte principal de la aplicación que desean cambiar.

Otro enfoque es configurar eventos en los diferentes formularios para comunicarse, y usar el formulario principal como un concentrador para pasar los mensajes de evento de un formulario a otro dentro de la aplicación.

+0

¿por qué no sólo tiene que utilizar los eventos? Esto es para lo que son, la comunicación entre objetos sin acoplamiento estrecho. –

+0

@Ed Swangren: Por eso también los sugerí. Es totalmente una opción, aunque requiere mucho más tiempo para hacer cada evento individual, ya que desea agregar nuevos ganchos, mientras que un singleton es más o menos una vez. Mi actividad favorita favorita es abstraer la UI del comportamiento principal de la aplicación. Ese núcleo es el singleton y puede tener eventos asociados. Entonces, toda la interfaz de usuario es solo una vista de los datos dentro del núcleo. Esto hace que los comportamientos de deshacer/rehacer sean mucho más fáciles. – ColinCren

+0

No veo ningún requisito para deshacer el comportamiento de deshacer, y estoy en desacuerdo con su afirmación que implica que organizar eventos es una tarea onerosa. Los singletons a menudo son una mala solución para cualquier problema. Iba a enumerar algunos argumentos de apoyo, pero encontré una lista bastante buena aquí: http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx –

19

Hacerlos Singleton no es una mala idea, pero personalmente no preferiría hacerlo de esa manera. Prefiero pasar la referencia de uno a otro formulario. Aquí hay un ejemplo.

Form1 activa Form2 para abrir. Form2 ha sobrecargado el constructor que toma la forma de llamada como argumento y proporciona su referencia a los miembros de Form2. Esto resuelve el problema de comunicación. Por ejemplo, he expuesto Label Property como público en Form1, que se modifica en Form2.

Con este enfoque puede hacer la comunicación de diferentes maneras.

Download Link for Sample Project

// Su Form1

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Form2 frm = new Form2(this); 
     frm.Show(); 
    } 

    public string LabelText 
    { 
     get { return Lbl.Text; } 
     set { Lbl.Text = value; } 
    } 
} 

// Su Form2

public partial class Form2 : Form 
{ 
    public Form2() 
    { 
     InitializeComponent(); 
    } 

    private Form1 mainForm = null; 
    public Form2(Form callingForm) 
    { 
     mainForm = callingForm as Form1; 
     InitializeComponent(); 
    } 

    private void Form2_Load(object sender, EventArgs e) 
    { 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     this.mainForm.LabelText = txtMessage.Text; 
    } 
} 

alt text http://demo.ruchitsurati.net/files/frm1.png

alt text http://demo.ruchitsurati.net/files/frm2.png

+1

-1, los eventos son un una solución mucho mejor –

+1

Este es de lejos el mejor camino a seguir. –

+6

@EdS. : ¿Realmente estás reduciendo una solución porque no crees que sea la mejor solución? Espero que no, porque esta es una solución totalmente válida y funcional. – Tipx

1

Acceda a los controles del formulario de esta manera: formname.controls[Index].
Puede fundido tipo de control según el caso, Ejemplo:
DataGridView dgv = (DataGridView) formname.Controls[Index];

1

Es fácil, en primer lugar se puede acceder a la otra forma de esta manera: (digamos que su otra forma es Form2)

//in Form 1 
Form2 F2 = new Form2(); 
foreach (Control c in F2.Controls) 
     if(c.Name == "TextBox1") 
      c.Text = "hello from Form1"; 

Eso es simplemente escriba en TextBox1 en Form2 desde Form1.

+0

Un buen tema relacionado: https://stackoverflow.com/a/1499088/4439444 – GntS

1

Hay una forma más, en caso de que no desee recorrer los controles "ALL" como sugirió Joe Dabones. Realice una función en Form2 y llámelo desde Form1.

public partial class Form2 : Form 
{ 
    public Form2() 
    { 
     InitializeComponent(); 
    } 

    public void SetIndex(int value) 
    { 
     lsbMyList.SelectedIndex = value; 
    } 
} 

public partial class Form1 : Form 
{ 
    public Form2 frm; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     frm=new Form2(); 
     frm.Show(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     frm.SetIndex(Int.Parse(textBox1.Text)); 
    } 
} 
Cuestiones relacionadas