2013-03-06 11 views
6

Cerco di trovare come assegnare un bool a una casella di controllo. Voglio che il mio valore checkbox.checked si aggiorni automaticamente quando i miei dati bool cambiano. So che per ComboBox ci sono gli attributi DataSource che lo fanno con una lista ma non sono in grado di trovare l'equivalente con la casella di controllo.bool come origine dati per un CheckBox (aggiornamento Bool in un altro thread rispetto a quello che sta interessando)

Provo con checkBox.DataBindings ma non sembra funzionare. D'altra parte non so veramente quale sia il terzo attributo.

checkBox.DataBindings.Add("Checked", DisableBugWatcher, "check"); 

Ho bisogno che perché ho due finestre indipendenti che rinfrescano lo stesso valore casella di controllo!

EDIT:

cerco di utilizzare l'evento per aggiornare la mia GUI principale, ma dicono: operazione cross-thread non valida: controllo 'casella' si accede da un thread diverso dal thread è stato creato sopra.

Il problema è il collegamento al fatto che il valore di bool viene aggiornato da un altro thread rispetto a quello che impatta.

+1

si prega di contrassegnare le domande in modo corretto. Se hai a che fare con winforms tagga la domanda 'winforms'. A proposito, ci sono molti framework UI all'interno di .net, winforms è solo uno di questi (meno performante, meno scalabile, meno efficiente, tra l'altro) –

+0

possibile duplicato di [Bound checkbox non aggiorna la sua origine dati] (http://stackoverflow.com/questions/2518191/bound-checkbox-does-not-update-its-datasource) –

risposta

1

Trovo un modo più semplice con un amico per risolvere il mio problema. Uso il DialogResult dal mio modulo. Quando torno dal modulo mi dà lo stato del clic del pulsante e mi dà il valore della casella di testo. Lo stesso codice funziona con il mio problema di checkbox.

Ecco un esempio di codice:

public partial class MainWindow : Form 
{ 

    private OtherWindow m_otherWindow; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     // Lazy create other window if it doesn't exist. 
     m_otherWindow = m_otherWindow ?? new OtherWindow(); 

     // Passe textbox value to other window. 
     m_otherWindow.PassedValue=textBox1.Text; 
     if (m_otherWindow.ShowDialog()==DialogResult.OK) 
     { 
      // Clicked ok : update textbox value with textbox value of other window. 
      textBox1.Text=m_otherWindow.PassedValue; 
     } 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     Close(); 
    } 
} 

public partial class OtherWindow : Form 
{ 

    /// <summary> 
    /// Value to be passed to the window. 
    /// </summary> 
    public string PassedValue 
    { 
     get { return textBox1.Text; } 
     set { textBox1.Text = value; } 
    } 

    public OtherWindow() 
    { 
     InitializeComponent(); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     DialogResult = DialogResult.OK; 
    } 
} 
5

Per far funzionare DataBindings, è necessario implementare INotifyPropertyChange nella classe che contiene il valore bool. Se si esegue myValue da un thread diverso dal thread dell'interfaccia utente, sarà necessario utilizzare un SynchronizationContext e inizializzare myObject nel thread dell'interfaccia utente.

public class myObject : INotifyPropertyChanged 
{ 
    // The class has to be initialized from the UI thread 
    public SynchronizationContext context = SynchronizationContext.Current; 

    bool _myValue; 
    public bool myValue 
    { 
     get 
     { 
      return _myValue; 
     } 
     set 
     { 
      _myValue = value; 

      // if (PropertyChanged != null) 
       // PropertyChanged(this, new PropertyChangedEventArgs("myValue")); 

      if (PropertyChanged != null) 
      { 
       context.Send(
        new SendOrPostCallback(o => 
         PropertyChanged(this, new PropertyChangedEventArgs("myValue")) 
        ), null); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

Quindi, impostare il DataBinding come questo:

checkBox1.DataBindings.Add("Checked", myObject.GlobalObject, "myValue"); 

Il primo parametro è la proprietà dell'oggetto dell'interfaccia utente che si desidera associare. Il secondo attributo è l'istanza dell'oggetto target, il terzo è il nome della proprietà dell'oggetto target che deve essere associato al primo.

Ho fatto del mio meglio per riflettere il tuo scenario utilizzando un timer che attiva myValue ogni secondo (che controlla la casella di controllo di conseguenza). Ecco il codice del Form che ho usato:

System.Timers.Timer x = new System.Timers.Timer(); 
myObject target; 

public Form1() 
{ 
    InitializeComponent(); 

    target = new myObject(); 

    x.Elapsed += (s, e) => 
     { 
      target.myValue = !target.myValue; 
     }; 
    x.Interval = 1000; 

    checkBox1.DataBindings.Add("Checked", target, "myValue"); 

    x.Start(); 
} 
+0

La tua risposta funzionerebbe perfettamente per un programma che funziona su un solo thread. Il mio problema è che non posso notificare un thread da un altro. Quindi il mio programma mi dice: _Cross-thread operation not valid: Control 'checkBox' ha avuto accesso da un thread diverso dal thread su cui è stato creato._ Vedi modifica per maggiori informazioni. – Othar

+0

Questo è più complicato di quanto sembri ... Devi usare un contesto di sincronizzazione e instanciate myObject nel thread dell'interfaccia utente (ho fatto nel costruttore del modulo).Quindi ho usato un timer per attivare myValue, che aggiorna la casella di controllo di conseguenza. Spero che sia d'aiuto. – Larry

+0

Grazie, con piccole modifiche a causa del mio programma, funziona bene !! – Othar