2009-06-10 16 views
30

Posso associare a una proprietà, ma non una proprietà all'interno di un'altra proprietà. Perchè no? per esempio.WPF: come associare a una proprietà nidificata?

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}"...> 
... 
    <!--Doesn't work--> 
    <TextBox Text="{Binding Path=ParentProperty.ChildProperty,Mode=TwoWay}" 
      Width="30"/> 

(Nota:.. Io non sto cercando di fare master-dettagli o nulla Entrambe le proprietà sono proprietà CLR normali)

Update: il problema era che la mia ParentProperty dipendeva da un oggetto in XAML essere inizializzato. Sfortunatamente quell'oggetto è stato definito successivamente nel file XAML rispetto al Binding, quindi l'oggetto era nullo nel momento in cui il mio ParentProperty veniva letto dal Binding. Dal momento che riorganizzare il file XAML sarebbe rovinare il layout, l'unica soluzione mi veniva in mente è stato quello di definire il Legatura in code-behind:

<TextBox x:Name="txt" Width="30"/> 

// after calling InitializeComponent() 
txt.SetBinding(TextBox.TextProperty, "ParentProperty.ChildProperty"); 

risposta

22

Tutto quello che posso pensare è che il ParentProperty viene cambiata dopo la Binding viene creato e non supporta la notifica delle modifiche. Ogni proprietà della catena deve supportare la notifica di modifica, sia che si tratti di un valore DependencyProperty o dell'implementazione di INotifyPropertyChanged.

+0

Sì, sembra essere la ragione. ParentProperty è di sola lettura ma dipende da un determinato controllo in XAML che viene inizializzato. Questo oggetto è definito nel file .xaml DOPO il Binding, quindi quando ParentProperty è stato chiamato, ha lanciato NullReferenceException. Non l'ho notato perché WPF lo ha inghiottito. Avrei dovuto controllare la finestra di output! – Qwertie

+0

Ora ho un nuovo enigma: come definire gli oggetti nell'ordine corretto in XAML senza rovinare il layout. – Qwertie

+0

Oppure posso in qualche modo rendere attivo il Binding fino a quando la Finestra non è completamente inizializzata prima di leggere la proprietà? Quando uso {Binding ElementName = xyz, ...}, funziona anche se xyz viene definito successivamente nel file XAML. Strano quindi che la mia ParentProperty (che usa l'elemento xyz) non funzioni solo perché xyz viene definito successivamente nel file XAML. – Qwertie

3

Sia la proprietà ParentProperty che la classe implementano INotifyPropertyChanged?

public class ParentProperty : INotifyPropertyChanged 
    { 
     private string m_ChildProperty; 

     public string ChildProperty 
     { 
      get 
      { 
       return this.m_ChildProperty; 
      } 

      set 
      { 
       if (value != this.m_ChildProperty) 
       { 
        this.m_ChildProperty = value; 
        NotifyPropertyChanged("ChildProperty"); 
       } 
      } 
     } 

     #region INotifyPropertyChanged Members 

     #endregion 
    } 

    public partial class TestClass : INotifyPropertyChanged 
    { 
     private ParentProperty m_ParentProperty; 

     public ParentProperty ParentProperty 
     { 
      get 
      { 
       return this.m_ParentProperty; 
      } 

      set 
      { 
       if (value != this.m_ParentProperty) 
       { 
        this.m_ParentProperty = value; 
        NotifyPropertyChanged("ParentProperty"); 
       } 
      } 
     } 
} 
    public TestClass() 

    { 
     InitializeComponent(); 
     DataContext = this; 
     ParentProperty = new ParentProperty(); 
     ParentProperty.ChildProperty = new ChildProperty(); 

     #region INotifyPropertyChanged Members 
     #endregion 
    } 
36

è anche possibile impostare DataContext per TextBox in XAML (non so se si tratta di una soluzione ottimale, ma almeno non devi fare nulla manualmente in codebehind eccezione di attuare INotifyPropertyChanged). Quando il vostro TextBox ha già DataContext (ereditato DataContext) si scrive codice come questo:

<TextBox 
    DataContext="{Binding Path=ParentProperty}" 
    Text="{Binding Path=ChildProperty, Mode=TwoWay}" 
    Width="30"/> 

essere consapevoli del fatto che fino a quando il DataContext per TextBox non è pronto vincolante per Text proprietà non verra 'stabilita' - è possibile aggiungere FallbackValue='error' come parametro Binding - sarà qualcosa di simile all'indicatore che ti mostrerà se l'associazione è OK o meno.

+4

+1 per il suggerimento su FallbackValue :) – Qwertie

Problemi correlati