2011-03-22 23 views
6

Tengo dos formularios. Diga FormA, FormB.Pasar datos al primer formulario del segundo formulario en C#

De FormA llamé a FormB usando frmB.Show();

En FormB, tengo dos cuadros de texto y un cuadro combinado de controles. Suponga que el usuario ingresa algunos datos en esos dos cuadros de texto y ha seleccionado un elemento del cuadro combinado en Form2 y ha hecho clic en el botón OK.

Después del clic quiero que los cuadros de texto ingresen los valores ingresados ​​por el usuario, el cuadro combinado seleccionó el valor del elemento a FormA.

¿Cómo puedo lograr esto usando C#.

+0

¿Puedes revisar tus etiquetas? ¿Es esto realmente una pregunta específica C# -4? Además, ¿son sus formularios WinForms? Gracias – Stuart

+0

Sí. Si hay una mejor solución en 4.0, está bien y es bueno saberlo. – venkat

+0

Cómo recuperar el control (ejecutar el punto de ejecución) de FormB a FormA. – venkat

Respuesta

3

O podría pasar un objeto de FormA a FormB y vincular sus propiedades a los controles en FormB. Si desea que se notifique a FormA cuando hace clic en el botón Aceptar, puede declarar un evento en su clase contenedor de datos, suscribirse a él en FormA y desencadenarlo desde FormB.

Sé DataContainer alguna clase se define

public class DataContainer 
{ 
    public event EventHandler AcceptedChanges; 
    protected virtual void OnAcceptedChanges() 
    { 
     if ((this.AcceptedChanges != null)) 
     { 
      this.AcceptedChanges(this, EventArgs.Empty); 
     } 
    } 

    public void AcceptChanges() 
    { 
     this.OnAcceptedChanges(); 
    } 

    public string Text1 { get; set; } 
    public string Text2 { get; set; } 
} 

in forma:

private void button4_Click(object sender, EventArgs e) 
{ 
    DataContainer data = new DataContainer(); 
    data.Text1 = "text1"; 
    data.Text1 = "text2"; 

    Form2 frm = new Form2(); 
    frm.Data = new DataContainer(); 
    data.AcceptedChanges += new EventHandler(data_AcceptedChanges); 
    frm.Show(); 
} 

void data_AcceptedChanges(object sender, EventArgs e) 
{ 
    // your code here 
} 

y en FormB:

public DataContainer Data { get; set; } 

private void Form2_Load(object sender, EventArgs e) 
{ 
    textBox1.DataBindings.Add(new Binding("Text", Data, "Text1")); 
    textBox2.DataBindings.Add(new Binding("Text", Data, "Text2")); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    Data.AcceptChanges(); 
} 

También debe aplicar INotifyPropertyChanging y INotifyPropertyChanged en DataContainer clase para jugar agradable con enlaces.

+0

Proporcionarme el código. – venkat

+0

Parece más código complejo. Necesito un código simple para manejar el requisito – venkat

+0

@sukumar: Try ShowDialog() :-) –

1

Una solución sucia, pero también la más rápida es hacer públicos esos controles. Esto lo puede hacer agregando la palabra pública en el archivo Form2.Decisgner.cs. Si FormA tiene una variable miembro o una variable local de FormB, se puede acceder al control (digamos TextBox1) con:

frmB.TextBox1.Text 

que ahora es accesible fuera FormB también.

+0

no entendiendo con su simple declaración. Por favor dígame con el código correctamente. – venkat

+0

¿Está utilizando formularios .NET C#? Cada formulario consta de al menos dos archivos, supongamos que su FormB se define en los archivos FormB.cs y FormB.Designer.CS. Y supongamos que los cuadros de texto se llaman TextBox1 y TextBox2. Compruebe dentro de su archivo FormB.Designer.cs para 'privado System.Windows.Forms.TextBox textBox1;' o análogo. Reemplace el trabajo 'privado' por 'público'. Ahora, desde donde sea que diga 'frmB.Show()' también puede decir 'frmB.textBox1.Text', que devolverá el texto en el cuadro de texto en ese punto. Por ejemplo, puede decir 'string myText = frmB.textBox1.Text'. – zmilojko

0

Si está en la misma página que debería ser capaz de leer directamente desde sus controles como TextBox1.Text, Textbox2.Text, Combobox.SelectedValue (supongo) Pero si su uso en páginas diferentes variables de sesión como: Session ["date1"] = TextBox1.Text; Session ["date2"] = TextBox2.Text; Session ["comboValue"] = Combobox.SelectedValue; y úselas para completar su formulario

+0

Estoy trabajando en aplicaciones web completas de C# WinApps y no ASP.NET. ¿Puedo usar variables de sesión en Windows? – venkat

0

Esto dependerá de cómo normalmente diseña sus aplicaciones.

  • Usted podría trabajar mediante el uso de un sistema impulsado caso donde se crearía eventos y delegados. Mencionado por @ Dave81
  • O puede crear propiedades que devuelven los valores dados/ seleccionados para que los padres les puede recuperar del objeto (quería decir diálogo pero no está seguro de lo que su uso).
  • O usted puede seguir @zmilojko y justo los puso pública, que es básicamente lo mismo que crear propiedades, pero más al lado oscuro de la codificación prácticas: D

Todos estos funcionarían pero todo depende de cómo te guste que tus aplicaciones estén estructuradas.

4

En el escenario que está describiendo, probablemente llamaría frmB.ShowDialog() en lugar de frmB.Show().

// Inside FormA open frmB as a modal dialog waiting for 
// OK or Cancel result using the following statement 

if (frmB.ShowDialog() == DialogResult.OK) 
{ 
    // Retrieve selected values from frmB here (while frmB is still not disposed) 
} 

Los beneficios de ShowDialog() son que:

  1. obtener el valor de retorno de la forma fácilmente lo que permite determinar que bien (en lugar de cancelar) se ha hecho clic para cerrarla.
  2. El formulario no se elimina inmediatamente cuando se cierra, lo que le permite recuperar los valores que desea.
  3. Al abrir frmB como un diálogo modal, evita tener que verificar las complejidades que pueden ocurrir si su usuario comienza a interactuar con formA mientras frmB está abierto.

NOTA: En el diseño de frmB usted tiene que establecer la propiedad DialogResult de permiso botón de control a DialogResult.OK a fin de que la forma de devolver el DialogResult correcta cuando se pulsa este botón (alternativamente puede también establecer this.DialogResult en el OK gestor de eventos Click del botón)

+0

@sukumar: ¿Has probado esta solución, o no es apropiado tener frmB abierto como un diálogo? –

+1

+1 Definitivamente suena como que la Forma B debería ser un Diálogo. – juharr

+0

@sukumar: Cuando llama a frnB.ShowDialog() el subproceso FormA no pasa inmediatamente a la siguiente instrucción, sino que espera hasta que frmB regrese con DialogResult. –

4

Puede crear un Manejador de eventos en FormB al que se suscribirá FormA. Además, agregue un par de propiedades públicas a FormB que representan los datos que desea que la FormA pueda usar. Luego, cuando FormB desactive el evento, FormA sabrá actualizar sus datos.

Nota: El principio clave en este ejemplo es implementar un Manejador de eventos (puede crear su propio tipo de controlador de eventos) que notifica a FormA cuando los datos están listos para actualizarse/visualizarse/etc. Con suerte, este ejemplo le permitirá ver cómo puede implementar un controlador de eventos para su situación particular.

Ejemplo:

FormA -

public partial class FormA : Form 
{ 
    //FormA has a private instance of FormB 
    private FormB formB = null; 
    public FormA() 
    { 
     InitializeComponent(); 
    } 

    void formB_OnDataAvailable(object sender, EventArgs e) 
    { 
     //Event handler for when FormB fires off the event 
     this.label1.Text = string.Format("Text1: {0}\r\nText2: {1}", 
      formB.Text1, formB.Text2); 
    } 

    private void InitializeFormB() 
    { 
     this.formB = new FormB(); 

     //FormA subscribes to FormB's event 
     formB.OnDataAvailable += new EventHandler(formB_OnDataAvailable); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     this.InitializeFormB(); 
     formB.Show(); 
    } 
} 

FormB -

public partial class FormB : Form 
{ 
    //Event that fires when data is available 
    public event EventHandler OnDataAvailable; 

    //Properties that expose FormB's data 
    public string Text1 { get; private set; } 
    public string Text2 { get; private set; } 

    public FormB() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     //Set the exposed properties, then fire off the event. 
     this.Text1 = this.textBox1.Text; 
     this.Text2 = this.textBox2.Text; 

     if (OnDataAvailable != null) 
      OnDataAvailable(this, EventArgs.Empty); 
    } 
} 
+0

Gracias Jed, bonito y limpio ejemplo. – LuckyLuke82

6

me acercaba a la forma sencilla .. pequeños adornos ..

  1. crear variables públicas en su formulario clase, es decir

    public string passVariable1 = "";

  2. si tiene cuadros de texto para ir a las propiedades, luego haga clic en el rayo y haga doble clic en el controlador de evento TextChanged vacío. Esto creará un fragmento de código en el comienzo del código que se ejecutará cuando el contenido del cuadro de texto haya cambiado. En este bloque de código, asigne el contenido del cuadro de texto a la variable pública correspondiente.

  3. es decir, mi variable pública fue

    problema de cadena pública = "";

    void privado txtIssue_TextChanged (remitente del objeto, EventArgs e) { issue = txtIssue.Text; }

  4. Agregar un botón y crear un evento de clic de este botón (basta con hacer doble clic en el botón en el panel de diseño). En el bloque de código de evento click, establezca el resultado de dilog en ok y oculte el

    this.DialogResult = DialogResult.OK;

    this.Hide();

  5. En la comprobación de código de ventana padre en el resultado de diálogo y agarrar los datos del formulario de variables públicas del formulario niño

if (f.ShowDialog() == DialogResult.OK) 
    { 
     string b = f.issue;    
     string e = f.year; 
     string f = f.month; 
    }; 
1

que estaba teniendo este mismo problema y vine con una idea que es un poco diferente. En mi caso, estoy haciendo un programa de tarjetas de memoria para mis dos hijos más pequeños y quería poder devolver la respuesta proporcionada al formulario principal (formulario nuevo para cada nueva pregunta de tarjeta de vocabulario para que el formulario principal pueda actualizar cuántos son izquierda, cuántos correctos, cuántos incorrectos, etc.) sin tener que agregar valores a una base de datos. Parece ser demasiado para algo que debería ser simple. Lo que hice fue crear una clase con 3 de cada tipo de variable. Pensé que tres de cada tipo serían suficientes para la mayoría de los trabajos.

Este es un ejemplo de mi nueva clase:

namespace ClassNamespace 
{ 
    public class ValueHolder 
    { 
    public int intValue1 { get; set; } 
    public int intValue2 { get; set; } 
    public int intValue3 { get; set; } 
    public long longValue1 { get; set; } 
    . 
    . 
    . 
    } 
} 

creo un nuevo ValueHolder (ValueHolder VH;) del formulario padre y pasarlo a la forma infantil. En el formulario secundario, creo un ValueHolder nuevo y luego lo configuro igual al objeto ValueHolder enviado en el constructor de clase del formulario secundario. Ahora, cuando se presiona la tecla enter (respuesta dada), puedo configurar vh.intValue1 igual a this.answerBox.text; ... bueno, tengo que usar int.tryparse(); Pero se entiende la idea. Entonces solo necesito hacer referencia a vh.intValue1 desde el formulario principal para obtener el valor ingresado.

forma de Padres:

for (int i = 0; i < limit; i++) 
{ 
    ValueHolder vh = new ValueHolder(); 

    ChildClass cc = new ChildClass(vh); 
    MessageBox.Show(vh.intValue1.ToString()); //to test that it works 
} 

y el niño formulario:

ValueHolder vh; 

public ChildClass (ValueHolder vhIncoming) 
{ 
    vh = vhIncoming; 
} 

private void answerBox_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.Enter) 
    { 
    vh.intValue1 = 1234; 
    } 
} 

Ésta parece ser la solución más simple para mi escenario.Sé que esta pregunta es antigua, pero quería agregar esta opción para cualquier persona en una posición similar. Solo agregue la clase a su proyecto, agregue más de un tipo o más tipos a la clase según sea necesario, enjuague repetido para proyectos futuros.

Cuestiones relacionadas