2011-06-08 13 views
7

Attualmente sto migrando un numero di comportamenti collegati che ho creato a Blend Behaviors in modo che supportino il trascinamento della selezione in Expression Blend. Ho notato che gli autori dei comportamenti di Blend tendono a definire le proprietà del comportamento come proprietà di dipendenza.Comportamenti di miscelazione: puoi legare alle loro proprietà?

Ho creato un comportamento, TiltBehaviour, che espone una proprietà di dipendenza pubblica, TiltFactor, di tipo double. In Expression Blend è possibile impostare il valore di questa proprietà, tuttavia, la possibilità di aggiungere una "Associazione dati ..." è grigio:

cannot bind to behaviour property

Ho anche notato che i comportamenti estendono DependencyObject, quindi non hanno uno DataContext e quindi non possono ereditare lo DataContext dell'elemento a cui sono collegati. Mi sembra una vera debolezza per me!

Quindi, la linea di fondo è, se non riesco a impostare un legame alla proprietà di dipendenza dei miei comportamenti in Blend, e non eredita uno DataContext, perché preoccuparsi di utilizzare le proprietà di dipendenza a tutti? Potrei semplicemente usare le proprietà CLR.

+1

Questo è molto strano, quale versione di Blend è? Non ho alcun problema a collegare le proprietà dell'elemento o le proprietà DataContext alle proprietà di dipendenza dei Behaviors con Blend 4 + Silverlight 4 ... – dain

+0

Dain, ho provato a eseguire il binding manualmente in Visual Studio, ad es. TiltFactor = "{Binding}" questo risulta in AG_E_PARSER_BAD_PROPERTY_VALUE, che spesso indica che stai vincolando a una proprietà di non dipendenza. Puoi indicare un esempio sul web di legare una proprietà di un comportamento? – ColinE

+1

Devi associare a una proprietà concreta del tipo corretto: TiltFactor = "{Binding TiltFactor}" – dain

risposta

4

Edit: Dain è corretto si può ancora legarsi al DataContext che si crea artificialmente, le persone quante volte hai visto si legano ad un SolidColorBrush.Color? Funziona anche se SolidColorBrush eredita da DependencyObject e quindi non ha DataContext.

Vedere this blog post on the inheritance context.

Il problema è che poiché i comportamenti sono collegati, non appaiono nell'albero logico e quindi non ereditano comunque un DataContext.

+0

+1 per il post del blog sul contesto di ereditarietà. Perché non l'ho visto prima ?! roba fantastica. – ColinE

+0

Tuttavia ... potrebbero essere fatti per ereditare il DataContext, come da questo post del blog: http://www.scottlogic.co.uk/blog/colin/2010/05/silverlight-multibinding-solution-for-silverlight- 4/ – ColinE

+0

È strano che questa informazione non sia nella documentazione o molto difficile da trovare. –

8

I comportamenti di miscelazione sarebbero quasi inutili a meno che non supportassero il binding! Ho ricreato il tuo comportamento di inclinazione e supporta il binding in Blend 4 senza problemi, quindi non so esattamente dove hai sbagliato. Forse puoi riprodurre il mio semplice esempio e quindi dedurre cosa c'è di sbagliato nella tua configurazione.

Ecco il (non funzionante) il comportamento di inclinazione con proprietà di dipendenza:

public class TiltBehavior : Behavior<FrameworkElement> 
{ 
    public double TiltFactor 
    { 
     get { return (double)GetValue(TiltFactorProperty); } 
     set { SetValue(TiltFactorProperty, value); } 
    } 

    public static readonly DependencyProperty TiltFactorProperty = 
     DependencyProperty.Register("TiltFactor", typeof(double), typeof(TiltBehavior), new UIPropertyMetadata(0.0)); 
} 

Poi basta creare una nuova finestra e rilasciare il comportamento sulla griglia e si fondono crea questo:

<Grid> 
    <i:Interaction.Behaviors> 
     <local:TiltBehavior/> 
    </i:Interaction.Behaviors> 
</Grid> 

e l'opzione "Data Binding ..." di Blend è disponibile nella scheda delle proprietà.

Ho provato questo con entrambi i progetti WPF e Silverlight. I comportamenti, i trigger e le azioni incorporati supportano tutti il ​​binding in virtù dell'utilizzo delle proprietà di dipendenza e tutti gli esempi di Blend utilizzano l'associazione pesantemente e quindi questo ha per funzionare.

In effetti è possibile eliminare un comportamento predefinito come FluidMoveBehavior nella griglia e verificare che Duration, che è una proprietà di dipendenza, supporti l'associazione. Se ciò non funziona, ho no idea di cosa sta succedendo!


Consideriamo allora come funziona il binding per queste strane bestie chiamate comportamenti.

Come programmatori WPF o Silverlight abbiamo familiarità con il binding per cose come FrameworkElement. Ha una proprietà chiamata DataContext che possiamo manipolare per controllare l'origine dell'associazione predefinita e che la proprietà è ereditata da elementi nidificati quando abbiamo non lo sostituisce con.

Ma i comportamenti (e i trigger e le azioni) sono non di tipo FrameworkElement. In definitiva sono derivati ​​da DependencyObject, come ci si potrebbe aspettare. Ma mentre possiamo usare il binding su qualsiasi classe derivata da DependencyObject, il nostro familiare DataContext manca a questo livello basso e quindi l'associazione deve fornire l'origine. Questo è non molto conveniente.

Quindi i comportamenti sono derivati ​​(su WPF comunque) da Animatable e Animatable sono derivati ​​da Freezable. La classe Freezable è dove la semplicità degli oggetti di dipendenza si interseca con la complessità degli elementi del framework. La classe Freezable è anche la classe base per cose più familiari come i pennelli e le fonti di immagini. Queste classi non richiedono la completa complessità di un elemento framework, ma vogliono partecipare, in modo limitato con gli elementi a cui sono associate.

Attraverso un complicato processo magico, Freezable istanze acquisiscono un contesto eredità: l'elemento framework sono più strettamente associati, e quando un difetto di legame è utilizzato (uno senza una sorgente), il Freezable utilizza il DataContext di cui è associato elemento anziché.

Infatti, man mano che si apprendono i comportamenti, lo AssociatedObject è un concetto centrale; per un comportamento è la cosa a cui è collegato il comportamento. Ma il punto importante è che tutti gli oggetti Freezable possono utilizzare il DataContext del loro AssociatedObject per proxy.

tutta questa magia è ciò che Josh Smith chiama il:

E così tutto questo porta fino a dire che a causa della Hillberg trucco Freezable, Miscela comportamenti supportano vincolante utilizzando il contesto dati del loro elemento associato come sorgente predefinita. Di conseguenza, i legami per i comportamenti sembrano "funzionare" senza alcuno sforzo da parte nostra. A causa di ciò, i comportamenti sono mille volte più utili.

Problemi correlati