2011-08-24 7 views
6

Ho cercato il mio piccolo cuore ed è del tutto possibile che mi manchi qualcosa di critico e ovvio.Aggiornamento WPF vincolante all'elemento in un array

Ho una BitArray e una serie di caselle di controllo che sono tenuti ad elementi dell'array, in questo modo:

<CheckBox IsChecked="{Binding Permissions[0]}" /> 
<CheckBox IsChecked="{Binding Permissions[1]}" /> 
... 
<CheckBox IsChecked="{Binding Permissions[5]}" /> 

ottengono i loro valori da quella proprietà in modo corretto, ma cambiando le caselle di controllo non sembra innescare il setter della proprietà.

Ho provato un esempio molto semplice con un singolo TextBox associato a un elemento di un array di stringhe.

class TestArray 
{ 
    private string[] _nameArray = new string[3]; 

    public TestArray() 
    { 
     _nameArray[1] = "test name"; 
    } 

    public string[] NameArray 
    { 
     get { return _nameArray; } 
     set { _nameArray = value; } 
    } 
} 

Ecco l'elemento dell'interfaccia utente:

<TextBox Text="{Binding NameArray[1], UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" /> 

Ancora una volta, questo TextBox prende il nome dal legame più che bene, ma non ha colpito il setter se cambio di esso.

Questa potrebbe essere totalmente una domanda di testa di ossa e potrebbe derivare da una grave mancanza di comprensione, quindi grazie per la vostra pazienza!

risposta

0

La cosa che manca è la notifica che il valore è cambiato. Quando si esegue il binding alle proprietà .NET standard (le cosiddette proprietà CLR), è necessario attivare un evento aggiuntivo per informare il controllo sulla modifica del valore. Dai un'occhiata a questo SO Question. Inoltre, MSDN potrebbe essere utile.

Posso anche raccomandare di leggere prima alcuni concetti base di WPF. Libri come WPF in Action (slightly outdated) o WPF Unleashed potrebbero aiutare.

2

Non ho mai provato questo approccio prima, ma non penso che funzionerà. Perché la proprietà che stai aspettando di vedere il fuoco del setter non è legata alla proprietà. NameArray non è lo stesso di NameArray [i].

Suggerirei di esaminare la ObservableCollection e il template per ottenere più checkbox. Ad esempio, è possibile creare una casella di riepilogo orizzontale delle caselle di controllo associate a ObservableCollection.

2

Anche in questo caso, questo TextBox ottiene il nome correttamente dall'associazione, ma non lo colpisce se lo cambio.

Non è necessario chiamare il setter: l'associazione non sostituisce l'array, sostituisce semplicemente un elemento dell'array. Se controlli i valori nella matrice, vedrai che riflettono le modifiche.

Funziona anche bene con un BitArray (ho appena provato con un array e un BitArray).

Tuttavia, gli array (e BitArray) non implementano INotifyPropertyChanged o INotifyCollectionChanged, quindi se ci sono altri collegamenti ai valori nell'array, non verranno aggiornati automaticamente. Avrai bisogno di un wrapper che implementa queste interfacce (ObservableCollection<T> per esempio)

2

Non si finisce nel setter perché non si modifica il valore per NameArray, si modifica il valore per un indice specifico nell'array, ad esempio NameArray [1]. Quindi il legame funziona ma non finirai nel setter.

Un approccio migliore consiste nell'usare un ObservableCollection e associarlo a un ItemsControl

+1

Penso che questo sia il mio prossimo corso di azione - che dovrebbe funzionare molto meglio. Grazie! – statikuz

1

Non sarà in grado di impostare elementi array individuali utilizzando vincolante elemento-index. Sarà necessario dividere la raccolta e configurare singole proprietà:

class TestArray : INotifyPropertyChanged 
{ 
    private string[] _nameArray = new string[3]; 

    public TestArray() 
    { 
     _nameArray[1] = "test name"; 
    } 

    public string Name 
    { 
     get { return _nameArray[0]; } 
     set { 
       _nameArray[0] = value; 
       NotifyPropertyChanged("Name"); 
      } 
    } 
} 

Sarà necessario utilizzare INotifyPropertyChanged come da MSDN (http://msdn.microsoft.com/en-us/library/ms743695.aspx).

+0

L'ho considerato ma non voglio una proprietà per ogni elemento dell'array; sembra un pessimo modo di farlo. – statikuz

0

questo ha funzionato per me:

NotifyPropertyChanged("") 
Problemi correlati