Ricerca 
it-ITen-US
Registrazione
Accedi
 
Autore:  Patrizia Cosolo
Pubblicato il:  2007/11/22

Panoramica delle Proprietà Subordinate (Dependency Properties)
Come iniziare a capire WPF Parte 6

Questa sesta traduzione da MSDN, introduce il sistema delle Proprietà Subordinate (Dependency Properties) di WPF, un altro dei componenti fondamentali di questo nuovo sistema per la generazione di interfacce utente e applicazioni con l'uso esteso di grafica e multimedia.

Introduzione

Come i precedenti ed i successivi, questo articolo è una traduzione della serie dei Getting Started di Windows Presentation foundation che si trovano su MSDN. Indicherò i link agli articoli originali in inglese e i link correlati saranno tutti alla versione inglese, fatto salvo che, man mano che tradurrò gli articoli più interessanti aggancerò anche la versione in italiano. I link agli articoli saranno effettuati con i due segnalini standard:

  • Inglese che porterà alla versione originale inglese.
  • Italiano che porterà alla versione italiana quando questa sarà scritta.

 

Panoramica delle Proprietà Subordinate

Windows Presentation Foundation (WPF) offre un insieme di servizi che può essere utilizzato per ampliare le funzionalità della proprietà del Common Language Runtime (CLR). Nel loro insieme, queste servizi sono generalmente identificate come il sistema delle proprietà di WPF. Una proprietà supportata dal sistema delle property di WPF è considerata una proprietà subordinata. Questa panoramica descrive il sistema delle proprietà di WPF e le funzionalità  di una proprietà subordinata, comprendendo l’utilizzo delle proprietà subordinate esistenti nel Linguaggio Estensibile di Markup per le Applicazioni [Extensible Application Markup Language: XAML n.d.t.] e nel codice. Inoltre questa panoramica, propone aspetti specifici delle proprietà subordinate, quali i metadati della proprietà subordinata, e anche come generare le proprie property subordinate in una classe personalizzata. 
Gli argomenti trattati in questo articolo sono:

Presupposti

Per l’argomento trattato in questo articolo si presume una vostra conoscenza di base del CLR e l’utilizzo di una programmazione ad oggetti. Inoltre, allo scopo di seguirne gli esempi, è necessaria la comprensione della codifica XAML e la conoscenza del metodo di scrittura delle applicazioni di WPF. Per maggiori informazioni, vedi Iniziare ad Utilizzare Windows Presentation Foundation.

Le Proprietà Subordinate e le Proprietà del CLR

In WPF, le proprietà sono generalmente esposte come proprietà del runtime di linguaggio comune (CLR). Ad un livello di base, potreste interagire direttamente con queste proprietà senza peraltro sapere mai che sono implementate come proprietà subordinate. Comunque dovreste prendere confidenza con alcune, se non con tutte, le caratteristiche del sistema delle property di WPF, allo scopo di trarne i benefici conseguenti al loro utilizzo.
 
Lo scopo delle proprietà subordinate è di fornire un metodo per calcolare il valore di una proprietà in base al valore di diversi inputs. Questi ultimi possono comprendere le proprietà del sistema, come i temi e le preferenze dell’utente; il meccanismo per la determinazione della proprietà just-in-time, come ad esempio il databinding e le animazioni/storyboards; i modelli ad uso molteplice [multiple-use templates n.d.t], come le risorse e gli stili, oppure i valori acquisiti attraverso le relazioni genitore-figlio con altri elementi sull’albero degli elementi.

Una proprietà subordinata può inoltre essere implementata per fornire la validazione autonoma [self-contained validation n.d.t.], i valori di default, i callback verificano la modifica ad altre proprietà ed un sistema che può imporre[coerce n.d.t.] i valori della proprietà basati potenzialmente sulle informazioni fornite a runtime. Le classi derivate possono modificare alcune caratteristiche specifiche di una proprietà  già esistente effettuando un overriding [sovrapposizione n.d.t.] dei metadati della proprietà subordinata, piuttosto che un overriding delle reali implementazioni delle proprietà esistenti o la creazione di nuove proprietà.
Nel riferimento dell’SDK (Software Developement Kit), potete identificare la proprietà subordinata dalla presenza della sezione Informazioni della Proprietà Subordinata, che si trova sulla pagina di riferimento gestita per quella proprietà. La sezione Informazioni della Proprietà Subordinata comprende il link DependencyProperty posto sul campo identificativo di quella proprietà subordinata. La sezione include anche una lista di opzioni per i metadati impostati per quella proprietà, informazioni di override per-class e altri dettagli.

Le Proprietà Subordinate a Supporto delle Proprietà del CLR

Le proprietà subordinate ed il sistema delle proprietà di WPF ampliano la funzionalità della proprietà fornendo un tipo che supporta la proprietà come alternativa al tradizionale metodo che implementa il supporto alla proprietà tramite un campo privato. Il nome di questo tipo di dato è DependencyProperty. Un altro importante tipo che definisce il sistema delle proprietà di WPF è DependencyObject. Il DependencyObject stabilisce la classe di base che può registrare e possedere una proprietà subordinata.
Il seguente è un sommario della terminologia utilizzata nella documentazione dell' SDK quando viene trattato l’argomento delle proprietà subordinate:

  • Proprietà subordinata: Una proprietà supportata dal tipo DependencyProperty.
  • Identificatore della proprietà subordinata: Un’istanza della DependencyProperty, che è ottenuta come un valore di ritorno quando si registra la proprietà subordinata, e quindi memorizzata come membro di una classe. Questo identificatore è utilizzato come parametro in molte delle APIs che interagiscono con il sistema della proprietà di WPF.
  • CLR “wrapper”: Le effettive implementazioni Get and Set della proprietà. Queste implementazioni incorporano l’identificatore della proprietà subordinata utilizzandolo nelle chiamate [calls n.d.t.] GetValue e SetValue, fornendo in questo modo il supporto alla proprietà tramite il sistema delle proprietà di WPF.

L’esempio seguente definisce la proprietà subordinata IsSpinning, e mostra la relazione che intercorre tra l’identificatore del DependencyProperty e la proprietà da esso supportata.

public static readonly DependencyProperty IsSpinningProperty 
    = DependencyProperty.Register( ... ); 

public bool IsSpinning 
{ 
    get 
    { 
        return (bool)GetValue(IsSpinningProperty); 
    } 
    set 
    { 
        SetValue(IsSpinningProperty, value); 
    } 
}

La convenzione per il nome della proprietà e del suo campo di supporto DependencyProperty è importante. Il nome del campo è sempre il nome della proprietà con l’aggiunta del suffisso Property. Per maggiori informazioni riguardo a questa regola e alle sue motivazioni, vedi Proprietà Subordinate Personalizzate Custom Dependency Properties.

L’Impostazione dei Valori della Proprietà

Le proprietà possono essere impostate sia utilizzando il markup XAML che via codice.

L’Impostazione dei Valori della Proprietà nel markup di XAML

Il seguente esempio in XAML stabilisce il colore di sfondo di un bottone come rosso. Questo esempio illustra il caso in cui il semplice valore di striga di un attributo di XAML viene convertito a tipo (type-converted) dal loader di XAML in un tipo di WPF nel codice generato ( ad esempio un Color convertito in un SolidColorBrush).

<Button Background="Red" Content="Button!"/>

XAML supporta svariate forme di sintassi  per l’impostazione delle proprietà. Quale sia la sintassi della quale servirsi per una particolare proprietà dipenderà dal tipo di valore che utilizza la proprietà, ma anche da altri fattori, come ad esempio la presenza di un type converter [convertitore di tipo n.d.t.]. Per maggiori informazioni sulla sintassi di XAML usata per impostare una proprietà, vedi Panoramica di XAML XAML overview e Terminologia della Sintassi di XAML  XAML Syntax Terminology
Come caso di sintassi senza attributo [non-attribute syntax n.d.t.], il seguente esempio di XAML mostra uno sfondo diverso per il bottone. Questa volta anziché impostare una semplice tinta unita, lo sfondo è impostato su un’immagine, con un elemento che rappresenta quell’immagine e la sua sorgente specificata come attributo dell’elemento annidato.Questo è un esempio di sintassi della property tramite elemento.

<Button Content="Button!"> 
    <Button.Background> 
        <ImageBrush ImageSource="wavy.jpg"/> 
    Button.Background> 
Button>

L’Impostazione delle Proprietà in Codice

L’impostazione dei valori della proprietà subordinata effettuata via codice, normalmente consiste solo in una chiamata all’insieme delle implementazioni esposte dal CLR”wrapper”.

Button myButton = new Button(); 
myButton.Width = 200.0;

Anche ottenere un valore di proprietà consiste essenzialmente in una chiamata all’implementazione get”wrapper”.

double whatWidth; 
whatWidth = myButton.Width;

Potete anche chiamare direttamente il sistema della proprietà delleAPIs GetValue e SetValue. Generalmente questo non è necessario se state utilizzando le proprietà già esistenti (i wrappers sono più pratici e forniscono una migliore esposizione delle proprietà per i tools dello sviluppatore), ma è appropriato per determinati scenari. 
Le proprietà possono anche essere impostate nel markup di XAML e in seguito rese accessibili in codice tramite il code-behind. Per maggiori dettagli, vedi Code-Behind e XAML Codebehind and XAML.

La Funzionalità della Proprietà Fornita dalla Proprietà Subordinata

Una proprietà subordinata fornisce funzionalità che estendono le funzionalità di una property, contrariamente a ciò che avviene per una proprietà supportata da un campo. Spesso, ciascuna di queste funzionalità rappresenta o supporta una specifica caratteristica del complessivo insieme di caratteristiche di WPF.

  •  Risorse
  • Collegamento dati (Data binding)
  • Stili
  • Animazioni
  • Overrides di metadati (Metadata overrides)
  • Ereditarietà del valore della proprietà

Risorse

Il valore di una proprietà subordinata può essere impostato referenziando una risorsa. Generalmente le risorse sono specificate come elementi figlio dell’elemento radice della pagina o della applicazione ( queste collocazioni abilitano l’accesso più conveniente alla risorsa). Il seguente esempio illustra come definire una risorsa SolidColorBrush.

<DockPanel.Resources> 
    <SolidColorBrush x:Key="MyBrush" Color="Gold"/> 
DockPanel.Resources>

Una volta che la risorsa è stata definita, potete riferirla ed utilizzarla per fornire il valore della proprietà:

<Button Background="{DynamicResource MyBrush}" 
    Content="I am gold" />

Questa particolare risorsa è riferita come una DynamicResource Markup Extension (in XAML potete usare il riferimento della risorsa sia statico che dinamico). Per utilizzare un riferimento di risorsa dinamico, dovete impostare i valori su una proprietà subordinata, così  l’utilizzo del riferimento di risorsa dinamico è specificatamente abilitato dal sistema delle proprietà di WPF. Per maggiori informazioni, vedi Panoramica delle Risorse Resources overview.

Nota

Le risorse sono considerate come un valore locale ciò significa che se voi impostate un altro valore locale, eliminerete il riferimento della risorsa. Per maggiori dettagli, vedi Priorità del Valore di una Proprietà Subordinata.Resources overview

Collegamento Dati (Data Binding)

Una proprietà subordinata può agganciare un valore attraverso il data binding. Il collegamento dati lavora mediante una specifica sintassi di estensione del markup di XAML, oppure servendosi dell’oggetto Binding via codice. Con il data binding, la determinazione del valore finale della proprietà è posticipato fino al momento dell’esecuzione del runtime, momento in cui il valore è ottenuto dalla sorgente dati.
L’esempio seguente imposta la proprietà di Content per un Button, servendosi di un Binding in XAML. Il collegamento utilizza un contesto di dati ereditato e una sorgente di dati XmlDataProvider(questo non compare nell’esempio). Il collegamento stesso specifica la proprietà della sorgente desiderata, all’interno della sorgente dati, mediante XPath.

<Button Content="{Binding XPath=Team/@TeamName}"/>
Nota

I collegamenti sono trattati come un valore locale, ciò significa che se voi impostate un altro valore locale, eliminerete il binding. Per maggiori dettagli, vedi Priorità del Valore di una Proprietà Subordinata.Resources overview
Le proprietà subordinate, e la classe DependencyObject, non supportano nativamente l’interfaccia INotifyPropertyChanged che permette la notifica delle modifiche del valore di proprietà della sorgente quando questi oggetti sono collegati ad una sorgente dati. Per maggiori informazioni su come generare proprietà utilizzabili in un data binding che possa riportare modifiche ad un destinatario di data binding, vedi Panoramica del Collegamento Dati Data Binding Overview.

Stili

Stili e modelli sono due dei più importanti scenari che motivano l’utilizzo delle proprietà subordinate. Gli stili sono particolarmente utili per l’impostazione delle proprietà che definiscono l’interfaccia utente(UI) dell’applicazione. Essi sono generalmente considerati come risorse di XAML. Gli stili interagiscono con il sistema della proprietà perché normalmente contengono i “setters”per particolari proprietà, includono anche i “triggers” dei quali si servono per modificare il valore della proprietà basato sul valore di real-time(tempo effettivo) di un altra proprietà.
L’esempio seguente genera uno stile veramente semplice (il quale sarebbe definito all’interno di un dizionario Resources; questo non è compreso nell’esempio), quindi lo stile generato viene applicato direttamente alla proprietà Style di un Bottone. Il setter che si trova all’interno dello stile imposta come grigia la proprietà Background del Bottone stilizzato(styled: capito niente?)

<Style x:Key="GreenButtonStyle"> 
    <Setter Property="Control.Background" Value="Green"/> 
Style>

Per maggiori informazioni, vedi Styling e ModellazioneStyling and Templating.

Animazioni

Le proprietà subordinate posso essere animate. Quando un’animazione viene applicata ed è eseguita, il valore animato agisce con una priorità(precedence:precedenza,diritto di precedenza) più alta rispetto a quella di qualsiasi altro valore (ad esempio un valore locale) possieda la proprietà. L’esempio seguente anima lo Sfondo della proprietà di un Bottone tecnicamente, lo Sfondo è animato mediante l’utilizzo della sintassi dell’elemento della proprietà al fine di determinare un SolidColorBrush bianco come Sfondo, quindi la proprietà Color di quel SolidColorBrush è la proprietà che viene direttamente animata.

<Button>I am animated 
    <Button.Background> 
        <SolidColorBrush x:Name="AnimBrush"/> 
    Button.Background> 
    <Button.Triggers> 
        <EventTrigger RoutedEvent="Button.Loaded"> 
            <BeginStoryboard> 
                <Storyboard> 
                    <ColorAnimation Storyboard.TargetName="AnimBrush" 
                        Storyboard.TargetProperty="(SolidColorBrush.Color)" 
                        From="Red" To="Green" 
                        Duration="0:0:5" 
                        AutoReverse="True" 
                        RepeatBehavior="Forever" /> 
                Storyboard> 
            BeginStoryboard> 
        EventTrigger> 
    Button.Triggers> 
Button>

Per maggiori informazioni su come animare le proprietà, vedi Panoramica dell’Animazione Animation Overview e Panoramica degli Storyboards Storyboard overview.

Overrides di Metadati (Metadata Overrides)

Quando derivate dalla classe che originariamente registra la proprietà subordinata, ne potete modificare alcuni comportamenti servendovi  dell’overriding dei metadati di quella proprietà. L’overriding di metadati dipende dall’identificatore DependencyProperty e non richiede di re-implementare la proprietà. La modifica di metadati è gestita nativamente dal sistema della proprietà; potenzialmente ciascuna classe detiene, su una base per-type, metadati individuali per tutte le proprietà ereditate dalle classi di base.
L’esempio seguente esegue l’overriding dei metadati di una DefaultSyleKey della proprietà subordinata. L’overriding di questi particolari metadati della proprietà subordinata è parte di uno schema di implementazione  che genera controlli i quali posso usare stili di default dai temi.

public class SpinnerControl : ItemsControl 
{ 
    static SpinnerControl() 
    { 
        DefaultStyleKeyProperty.OverrideMetadata( 
        typeof(SpinnerControl), 
        new FrameworkPropertyMetadata(typeof(SpinnerControl)) ); 
    } 
}

Per maggiori informazioni riguardo all’overriding o all’ottenimento di metadati della proprietà, vedi Metadati delle Proprietà Subordinate Dependency Property Metadata.

L’Ereditarietà del Valore della Proprietà

Un elemento può ereditare il valore di una proprietà subordinata dal proprio genitore nell’albero degli elementi.

Nota

Il comportamento dell’ereditarietà del valore della proprietà non è globalmente abilitato per tutte le proprietà subordinate, poichè il tempo di calcolo per l’ereditarietà potrebbe avere un certo impatto sulla performance. L’ereditarietà del valore della proprietà è generalmente abilitato solamente per quelle proprietà nelle quali un particolare scenario  indica che detta ereditarietà è appropriata. Potete stabilire se una proprietà subordinata eredita esaminando la sezione Informazioni sulla Proprietà Subordinata che troverete nei riferimenti del SDK (Software Developement Kit).

L’esempio seguente mostra un Binding e imposta la proprietà DataContext che specifica la sorgente del binding, ciò non è stato illustrato nel precedente esempio di binding. Il valore della proprietà DataContext eredita, di conseguenza qualunque dei successivi bindings sugli elementi figlio non ha la necessità di specificare di nuovo la sorgente specificata sull’elemento genitore StackPanel.

<StackPanel Canvas.Top="50" 
    DataContext="{Binding Source=
    {StaticResource XmlTeamsSource}}"> 
    <Button Content="{Binding XPath=Team/@TeamName}"/> 
StackPanel>

Per maggiori informazioni, vedi L’Ereditarietà del Valore della Proprietà  Property Value Inheritance.

La Priorità del Valore della Proprietà Subordinata

Quando acquisite il valore di una proprietà subordinata,ottenete potenzialmente  un valore che viene impostato su quella determinata proprietà attraverso ognuno degli altri inputs basati sulla proprietà che partecipano al sistema della property di WPF. La priorità del valore della proprietà subordinata esiste affinchè una varietà di scenari, dovuti ai diversi modi in cui le proprietà ottengono i loro valori, possa interagire in modo prevedibile.
Consideriamo il seguente esempio. Esso comprende uno stile che si applica a tutti i bottoni e alle loro proprietà di Sfondo, ma poi specifica anche un bottone con un valore di Sfondo impostato localmente.

Nota

La documentazione di SDK usa i termini “valore locale (local value)” e “valore impostato localmente (locally set value)” nelle occasioni in cui tratta l’argomento delle proprietà subordinate. Un valore impostato localmente è un valore della proprietà che è impostato direttamente in codice su un’istanza di oggetto oppure, se considerato come un attributo, viene impostato su un elemento via XAML. Effettivamente, per il primo bottone, la proprietà è impostata due volte, ma un solo valore è valido(applies): quello con la priorità più alta. Il valore impostato localmente ha la priorità più alta (fatta eccezione per un’animazione che è eseguita, ma in questo esempio non viene impiegata animazione), e perciò viene usato al posto del valore del setter di stile, per lo sfondo del primo bottone. Il secondo bottone non ha un valore locale (e nessun altro valore con priorità più alta di quella di un setter di stile) e perciò il suo sfondo proviene dal setter di stile.

<StackPanel> 
    <StackPanel.Resources> 
        <Style x:Key="{x:Type Button}" 
            TargetType="{x:Type Button}"> 
            <Setter Property="Background" Value="Red"/> 
        Style> 
    StackPanel.Resources> 
    <Button Background="Green">
        I am NOT red!
    Button> 
    <Button>I am styled redButton> 
StackPanel>

Perché esiste la Priorità del Valore della Proprietà Subordinata?
Generalmente, non si predispongono stili da applicare sempre che oscurano anche il valore impostato localmente di un elemento individuale (altrimenti, sarebbe veramente difficile utilizzare o stili o elementi in generale). Perciò, i valori che provengono dagli stili operano con una priorità più bassa di quella del valore impostato localmente. Per un elenco più approfondito delle proprietà subordinate e per capire da dove potrebbe provenire l’effettivo valore della proprietà, vedi La Priorità del Valore della Proprietà SubordinataDependency Property Value Precedence.

Nota

Ci sono numerose proprietà definite sugli elementi di WPF che non sono proprietà subordinate. In generale, le proprietà vengono implementate come proprietà subordinate solo quando c’è la necessità di supportare almeno uno degli scenari abilitati dal sistema della proprietà: databinding, styling, animazione, supporto del valore di default, ereditarietà, proprietà collegate o invalidazione.

L’Apprendimento di altre Nozioni sulle Proprietà Subordinate

  • Una proprietà collegata è un tipo di proprietà che supporta una sintassi specializzata di XAML. Essa spesso non ha una corrispondenza biunivoca (1:1 correspondence) con una proprietà del runtime di linguaggio comune (CLR), e non è necessariamente una proprietà subordinata. Lo scopo principale di una proprietà collegata è quello di permettere agli elementi figlio di riportare i valori della proprietà all’elemento genitore anche se, l’elemento genitore e l’elemento figlio, non possono entrambe possedere quella proprietà come parte dei membri di classe elencati. Uno dei principali scenari d'uso  è  abilitare gli elementi figlio ad informare il genitore sul modo in cui verrebbero presentati all’interfaccia utente (UI); come esempio, vedi Dock o Left. Per maggiori dettagli, vedi Panoramica delle Proprietà Collegate Attached Properties overview.
  • Gli sviluppatori di componenti o di applicazioni possono avere la necessità di generare  proprietà subordinate personalizzate allo scopo di abilitare funzionalità, come ad esempio il databinding o il supporto di stili, oppure utilizzarle per l’invalidazione  e come supporto di forzatura del valore. Per maggiori dettagli, vedi Proprietà Subordinate Personalizzate Custom Dependency Properties.
  • Le proprietà subordinate dovrebbero generalmente essere definite come proprietà pubbliche, accessibili o almeno rintracciabili o rilevabili da qualsiasi caller che abbia accesso ad un’istanza. Per maggiori dettagli, vedi Sicurezza della Proprietà Subordinata Custom Dependency Properties

© 2007 Microsoft Corporation
Trademark information is available at http://www.microsoft.com/library/toolbar/3.0/trademarks/en-us.mspx

Traduzione a cura di Patrizia Cosolo, Revisione tecnica a cura di Sabrina Cosolo.



       
Articoli|Webcast|Risorse|Utility
© 2007-2010 by DotNetWork  .:.  Condizioni d'uso  .:.  Privacy  .:.  Accedi  .:.