2009-07-23 9 views
21

Sono un po 'disorientato su come le Proprietà associate trasmettano effettivamente i loro valori a elementi padre o figlio. TextElement.FontFamily fa in modo che gli elementi figlio ereditino il valore assegnato a quella proprietà (un'operazione apparentemente a valle, da padre a figlio). Grid.Column fa in modo che un elemento padre visualizzi quel figlio in una posizione particolare (un'operazione apparentemente a monte, da figlio a padre). In che modo i valori della proprietà allegata sanno scorrere verso l'alto o verso il basso? La mia concezione di questo è errata o manca un pezzo che metterà tutto questo in prospettiva?Come funzionano esattamente le Proprietà associate in WPF?

<StackPanel TextElement.FontFamily="Wingdings"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 

     <Button Grid.Column="1" Content="My Button"/> 
    </Grid> 
</StackPanel> 

risposta

38

Ci sono due concetti qui: proprietà di dipendenza e proprietà di dipendenza allegate. Le "Proprietà associate" sono proprietà di dipendenza e, come tale, dipendono dal supporto property value inheritance.

Informazioni sulle proprietà di dipendenza di base, una dichiarazione molto approssimativa sarebbe che esse ereditano fondamentalmente i loro valori dagli elementi padre nell'albero wpf (logico/visivo). Una proprietà di dipendenza (associata o meno) eredita il suo valore "al ribasso" se il suo metadata è impostato con FrameworkPropertyMetadataOptions. Inherit flag, e in molti casi è così.

proprietà associate sono proprietà che possono essere impostate su qualsiasi oggetto wpf (sostanzialmente, almeno DependencyObject) tramite il metodo DependencyObject.SetValue. Lo scopo di questo meccanismo è di "collegare" ad altri oggetti le informazioni necessarie agli oggetti padre, non gli oggetti figli stessi. Ad esempio, Grid.Row è una proprietà associata richiesta dalla griglia per posizionare gli elementi all'interno dell'area di rendering.

Le proprietà di dipendenza vengono automaticamente "ridotte" automaticamente dal sistema di oggetti wpf.

Le proprietà collegate vengono esaminate "verso l'alto" in modo esplicito, nel codice di oggetti specifici. Nel caso di Grid, al momento di determinare dove posizionare gli elementi, controlla il valore delle proprietà associate a Grid.Row e Grid.Column su ciascun oggetto contenuto.

Spesso è anche la tecnica per creare proprietà associate personalizzate che modificano in qualche modo gli oggetti a cui sono collegate (ad esempio, lo Drag'n'Drop functionality via attached properties).

Come nota aggiuntiva, un buon esempio di proprietà associata ereditata è TextElement.FontFamily. Le proprietà Grid.Row e Grid.Column non hanno il flag Inherits.

TextElement.FontFamily, dal riflettore:

FontFamilyProperty = DependencyProperty.RegisterAttached("FontFamily", typeof(FontFamily), typeof(TextElement), new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily, FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(TextElement.IsValidFontFamily)); 

Grid.Row, dal riflettore:

RowProperty = DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid), new FrameworkPropertyMetadata(0, new PropertyChangedCallback(Grid.OnCellAttachedPropertyChanged)), new ValidateValueCallback(Grid.IsIntValueNotNegative)); 
+1

Interessante e informativo. Che dire di questo scenario, però: Una griglia 2x2 (A) contiene una griglia 2x2 (B). La griglia B contiene un pulsante. Se Grid B ha la griglia.La proprietà Column Attached impostata su 1 (quindi appare nella seconda colonna della sua griglia padre, Grid A), non dovrebbe che la Proprietà associata si sovrapponga al pulsante Grid B, quindi il pulsante appare nella seconda colonna di Grid B? – Pwninstein

+1

Buona domanda, aggiunta di informazioni alla risposta. –

+0

Fantastico! Ha molto più senso ora, grazie !! – Pwninstein

2

Da MSDN:

Sebbene proprietà associate sono impostabili su qualsiasi oggetto, ciò non significa automaticamente che l'impostazione della proprietà produrrà un risultato tangibile, o che il valore sarà mai utilizzato da un altro oggetto. Generalmente, le proprietà associate sono concepite in modo che gli oggetti provenienti da una vasta gamma di possibili gerarchie di classi o relazioni logiche possano riportare informazioni comuni sul tipo che definisce la proprietà associata. Il tipo che definisce la struttura divisoria segue tipicamente uno di questi modelli:

  • tipo che definisce il proprietà associata è progettato in modo che possa essere l'elemento principale degli elementi che impostare valori per il allegato proprietà. Il tipo quindi itera i suoi oggetti figlio tramite la logica interna rispetto a una struttura ad albero di oggetti, ottiene i valori e agisce su tali valori in qualche modo.

  • Il tipo che definisce l'allegato sarà utilizzato come elemento figlio per una varietà di possibili elementi madri e modelli di contenuto.

  • Il tipo che definisce la proprietà allegata rappresenta un servizio. Altri tipi impostano i valori per la proprietà allegata. Quindi, quando l'elemento che imposta la proprietà viene valutato nel contesto del servizio, i valori delle proprietà allegate vengono ottenuti tramite la logica interna della classe di servizio.

Un esempio di un genitore definita Attached Property

Il più tipico scenario in cui WPF definisce una proprietà associata è quando un elemento padre supporta una collezione elemento figlio, e implementa anche un comportamento in cui il le specifiche del comportamento sono riportate singolarmente per ogni elemento figlio.

DockPanel definisce la proprietà associata DockPanel.Dock e DockPanel ha codice di classe come parte della sua logica di rendering (in particolare, MeasureOverride e ArrangeOverride). Un'istanza di DockPanel controllerà sempre se alcuni dei suoi elementi figlio immediati hanno impostato un valore per DockPanel.Dock. In tal caso, tali valori diventano input per la logica di rendering applicata a quel particolare elemento figlio. Le istanze di DockPanel nidificate trattano ciascuna le proprie raccolte di elementi figlio immediati, ma tale comportamento è specifico dell'implementazione per il modo in cui DockPanel elabora i valori di DockPanel.Dock. È teoricamente possibile avere proprietà associate che influenzano elementi al di là del genitore immediato. Se il DockPanel.La proprietà associata al dock è impostata su un elemento che non ha un elemento padre di DockPanel che agisca su di esso, nessun errore o eccezione viene sollevata. Ciò significa semplicemente che è stato impostato un valore di proprietà globale, ma non ha un genitore DockPanel corrente che potrebbe consumare le informazioni.

0

In parole semplici questo è come lo capisco (per favore correggetemi se sbaglio).

Un oggetto (A) implementa una proprietà che si collega a un altro oggetto (B) (l'oggetto B non sa nemmeno dell'esistenza di questa proprietà "attaccabile"). L'oggetto B deve ereditare da DependencyObject.

L'oggetto A implementa anche un metodo statico per verificare la sua proprietà "attaccabile" in altri oggetti, A.GetAttachedProperty (B).

Se B ha la proprietà associata da A, A.GetAttachedProperty leggerà e restituirà il valore. Altrimenti A proverà a leggerlo e restituirà null poiché non è lì.