2011-01-27 17 views
9

Ho due classi Form, una delle quali ha un ListBox. Ho bisogno di un setter per la proprietà SelectedIndex dello ListBox, che desidero chiamare dal secondo Form.Come accedere a un controllo di modulo per un altro modulo?

Al momento sto facendo il seguente:

Modulo 1

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

Modulo 2

private ControlForm mainForm; // form 1 

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

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

È questo il modo migliore per farlo?

+0

[L'interazione tra forme -? Come modificare un controllo di un modulo da un'altra forma] (https://stackoverflow.com/a/38769212/3110834) –

risposta

2

Io di solito uso il modello Singleton Design per qualcosa di simile a questo http://en.wikipedia.org/wiki/Singleton_pattern. Creerò il modulo principale in cui l'applicazione è in esecuzione sotto il singleton e quindi creo i metodi di accesso ai moduli e ai controlli che desidero toccare in altre aree. Le altre forme possono quindi ottenere un puntatore al controllo che desiderano modificare, oppure i dati nella parte principale dell'applicazione che desiderano modificare.

Un altro approccio consiste nell'impostare eventi sui diversi moduli per la comunicazione e utilizzare il modulo principale come hub di ordinamento per passare i messaggi di evento da un modulo all'altro all'interno dell'applicazione.

+0

Perche 'non basta utilizzare gli eventi? Questo è ciò per cui sono, la comunicazione tra oggetti senza accoppiamento stretto. –

+0

@Ed Swangren - Ecco perché li ho suggeriti anch'io. È totalmente un'opzione, anche se richiede molto più tempo per fare ogni singolo evento, come si desidera aggiungere nuovi hook, mentre un singleton è praticamente una cosa una tantum. La mia cosa preferita da fare è astrarre l'interfaccia utente dal comportamento principale dell'applicazione. Questo nucleo è il singleton e può avere eventi collegati ad esso. Quindi tutta l'interfaccia utente è solo una vista dei dati all'interno del nucleo. Ciò rende molto più facile l'esecuzione di comportamenti di annullamento/ripetizione. – ColinCren

+0

Non vedo alcun requisito per il comportamento di annullamento del ripristino e non sono d'accordo con la tua affermazione che implica che l'impostazione degli eventi sia un'attività onerosa. I single sono spesso una soluzione schifosa per qualsiasi problema. Stavo per elencare alcuni argomenti di supporto, un po 'ho trovato una lista abbastanza buona qui: http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx –

19

Rendendoli Singleton non è una cattiva idea, ma personalmente non preferirei farlo in quel modo. Preferirei passare il riferimento di uno a un altro modulo. Ecco un esempio.

Form1 attiva il Form2 per l'apertura. Form2 ha sovraccaricato il costruttore che prende la forma chiamante come argomento e fornisce il suo riferimento ai membri di Form2. Questo risolve il problema di comunicazione. Ad esempio, ho esposto la proprietà Label come pubblica in Form1 che viene modificata in Form2.

Con questo approccio è possibile effettuare comunicazioni in diversi modi.

Download Link for Sample Project

// tuo 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; } 
    } 
} 

// tuo 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, gli eventi sono un soluzione molto migliore. –

+1

Questo è di gran lunga il modo migliore per andare. –

+6

@ Eds. : Stai davvero ridimensionando una soluzione perché non pensi che sia la soluzione migliore? Spero di no perché questa è una soluzione totalmente valida e funzionante. – Tipx

1

Accedere ai controlli del modulo in questo modo: formname.controls[Index].
Si può lanciare come appropriato tipo di controllo, Esempio:
DataGridView dgv = (DataGridView) formname.Controls[Index];

1

E 'facile, in primo luogo è possibile accedere al altra forma in questo modo: (diciamo l'altra forma è Form2)

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

Ecco Si, basta scrivere in TextBox1 in Form2 da Form1.

+0

Un argomento correlato: https://stackoverflow.com/a/1499088/4439444 – GntS

1

C'è un altro modo, nel caso in cui non si desideri eseguire il ciclo di controlli "TUTTI" come suggerito da Joe Dabones. Crea una funzione in Form2 e chiama da 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)); 
    } 
} 
Problemi correlati