Cenni preliminari sulle proprietà associate

Una proprietà associata è un concetto definito da Extensible Application Markup Language (XAML). Una proprietà associata deve essere utilizzata come un tipo di proprietà globale che è possibile impostare su qualsiasi oggetto. In Windows Presentation Foundation (WPF), le proprietà associate vengono definite in genere come un tipo specializzato di proprietà di dipendenza che non dispone del "wrapper" della proprietà convenzionale.

Nel presente argomento sono contenute le seguenti sezioni.

  • Prerequisiti
  • Vantaggi offerti dall'utilizzo delle proprietà associate
  • Proprietà associate in XAML
  • Utilizzo delle proprietà associate da parte del tipo proprietario
  • Proprietà associate nel codice
  • Metadati della proprieta associata
  • Proprietà associate personalizzate
  • Ulteriori informazioni sulle proprietà associate
  • Argomenti correlati

Prerequisiti

Questo argomento si presuppone la conoscenza delle proprietà di dipendenza dal punto di vista di un consumer delle proprietà di dipendenza esistenti nelle classi Windows Presentation Foundation (WPF), nonché la lettura della sezione Cenni preliminari sulle proprietà di dipendenza. Per capire gli esempi illustrati in questo argomento, è necessaria inoltre la conoscenza di Extensible Application Markup Language (XAML) e della procedura di scrittura delle applicazioni WPF.

Vantaggi offerti dall'utilizzo delle proprietà associate

Una delle finalità di una proprietà associata consiste nel consentire a diversi elementi figlio di specificare valori univoci di una proprietà effettivamente definita in un elemento padre. Un'applicazione specifica di questo scenario consente agli elementi figlio di notificare all'elemento padre la modalità con cui devono essere presentati nell'user interface (UI). Un esempio è rappresentato dalla proprietà DockPanel.Dock. La proprietà DockPanel.Dock viene creata come proprietà associata perché è progettata in modo da essere impostata sugli elementi contenuti all'interno di un oggetto DockPanel, anziché sull'oggetto DockPanel stesso. La classe DockPanel definisce il campo DependencyProperty statico denominato DockProperty e fornisce quindi i metodi GetDock e SetDock come funzioni di accesso pubbliche per la proprietà associata.

Proprietà associate in XAML

In XAML, è possibile impostare le proprietà associate utilizzando la sintassi ProviderProprietàAssociata.NomeProprietà 

Di seguito viene riportato un esempio della procedura di impostazione di DockPanel.Dock in XAML:

<DockPanel>
  <CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>

Notare che l'utilizzo è sotto certi aspetti simile a una proprietà statica; si fa sempre riferimento al tipo DockPanel proprietario della proprietà associata e in grado di registrarla, piuttosto che a qualsiasi istanza specificata per nome.

Inoltre, poiché una proprietà associata in XAML è un attributo che viene impostato nel markup, solo l'operazione di impostazione ha una certa rilevanza. Non è possibile ottenere direttamente una proprietà in XAML, sebbene esistano alcuni meccanismi indiretti per il confronto dei valori, ad esempio i trigger negli stili (per informazioni dettagliate, vedere Applicazione di stili e modelli).

Implementazione delle proprietà associate in WPF

In Windows Presentation Foundation (WPF), la maggior parte delle proprietà associate che esistono nei tipi WPF sono implementate come proprietà di dipendenza. Le proprietà associate sono un concetto XAML, mentre le proprietà di dipendenza sono un concetto WPF. Dal momento che le proprietà associate°WPF sono proprietà di dipendenza, supportano concetti di proprietà di dipendenza, ad esempio i metadati delle proprietà e i relativi valori predefiniti.

Utilizzo delle proprietà associate da parte del tipo proprietario

Anche se le proprietà associate possono essere impostate su qualsiasi oggetto, ciò non significa che l'impostazione della proprietà produce un risultato tangibile o che il valore sarà utilizzato da un altro oggetto. In genere, le proprietà associate sono concepite in modo che gli oggetti provenienti da un'ampia varietà di possibili gerarchie di classi o di relazioni logiche possano ciascuno riportare informazioni comuni al tipo che definisce la proprietà associata. Il tipo che definisce la proprietà associata si attiene di regola a uno di questi modelli:

  • Il tipo che definisce la proprietà associata è progettato in modo da poter essere l'elemento padre degli elementi che imposteranno i valori per la proprietà associata. Il tipo scorre quindi gli oggetti figlio attraverso la logica interna in base a una struttura ad albero degli oggetti, ottiene i valori e agisce in qualche modo su tali valori.

  • Il tipo che definisce la proprietà associata sarà utilizzato come elemento figlio per diversi elementi padre e modelli di contenuto possibili.

  • Il tipo che definisce la proprietà associata rappresenta un servizio. Gli altri tipi impostano i valori per la proprietà associata. Pertanto, quando l'elemento che imposta la proprietà viene valutato nel contesto del servizio, i valori della proprietà associata vengono ottenuti tramite la logica interna della classe del servizio.

Esempio di proprietà associata definita dall'elemento padre

Lo scenario più tipico in cui WPF definisce una proprietà associata è quello in cui un elemento padre supporta un insieme di elementi figlio e implementa inoltre un comportamento tale che le specifiche del comportamento vengono segnalate singolarmente per ogni elemento figlio.

L'oggetto DockPanel definisce la proprietà associata DockPanel.Dock e l'oggetto DockPanel dispone di un codice a livello di classe come parte della logica di rendering (in particolare, gli oggetti MeasureOverride e ArrangeOverride). Un'istanza di DockPanel verificherà sempre se uno dei relativi elementi figlio immediati ha impostato un valore per la proprietà DockPanel.Dock. In questo caso, tali valori diventano l'input per la logica di rendering applicata a quel particolare elemento figlio. Le istanze annidate di DockPanel gestiscono ciascuna i propri insiemi di elementi figlio immediati; tuttavia tale comportamento varia in base all'implementazione, a seconda del modo in cui DockPanel elabora i valori DockPanel.Dock. In teoria è possibile che alcune proprietà associate abbiano effetto su elementi più distanti dell'elemento padre immediato. Se la proprietà associata DockPanel.Dock è impostata su un elemento sul quale non agisce alcun elemento padre DockPanel, non verranno generati errori o eccezioni. Ciò significa semplicemente che un valore della proprietà globale è stato impostato, ma al momento non è presente alcun elemento padre DockPanel che possa utilizzare le informazioni.

Proprietà associate nel codice

Le proprietà associate in WPF non dispongono dei tipici metodi "wrapper" CLR per ottenere o impostare facilmente l'accesso. Ciò è dovuto al fatto che la proprietà associata non è necessariamente inclusa nello spazio dei nomi CLR per le istanze in cui la proprietà è impostata. Tuttavia, un lettore XAML deve essere in grado di impostare tali valori durante l'elaborazione di XAML. Affinché una proprietà associata sia effettiva, il tipo proprietario della proprietà associata deve implementare i metodi delle funzioni di accesso dedicati nel formato GetNomeProprietà e SetNomeProprietà. Questi metodi della funzione di accesso dedicati sono anche utili per ottenere o impostare la proprietà associata nel codice. Dal punto di vista del codice, una proprietà associata è simile a un campo di backup che dispone di funzioni di accesso ai metodi anziché di funzioni di accesso alle proprietà e tale campo di backup può trovarsi in qualsiasi oggetto senza che sia necessario definirlo in modo specifico.

Nell'esempio seguente viene illustrato come impostare una proprietà associata nel codice. In questo esempio, myCheckBox è un'istanza della classe CheckBox.

      Dim myDockPanel As New DockPanel()
      Dim myCheckBox As New CheckBox()
      myCheckBox.Content = "Hello"
      myDockPanel.Children.Add(myCheckBox)
      DockPanel.SetDock(myCheckBox, Dock.Top)
DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);

Analogamente al caso di XAML, se myCheckBox non fosse già stato aggiunto come elemento figlio di myDockPanel nella terza riga di codice, la quarta riga di codice non genererebbe un'eccezione, ma il valore della proprietà non potrebbe interagire con un elemento padre DockPanel, pertanto l'operazione non avrebbe alcun esito. Solo un valore di DockPanel.Dock impostato su un elemento figlio combinato con la presenza di un elemento padre DockPanel produrrà un comportamento effettivo nell'applicazione sottoposta a rendering. In questo caso, è possibile impostare la proprietà associata, quindi effettuare l'associazione alla struttura ad albero. In alternativa, è possibile effettuare l'associazione alla struttura ad albero, quindi impostare la proprietà associata. Qualunque sia l'ordine delle azioni, il risultato è il medesimo.

Metadati della proprieta associata

Al momento della registrazione della proprietà, l'oggetto FrameworkPropertyMetadata viene impostato in modo da specificare le caratteristiche della proprietà, ad esempio se la proprietà influisce sul rendering, sulla misurazione e così via. In genere i metadati di una proprietà associata non sono diversi rispetto a quelli presenti in una proprietà di dipendenza. Se si specifica un valore predefinito in un override per i metadati di una proprietà associata, tale valore diviene il valore predefinito della proprietà associata implicita nelle istanze della classe che esegue l'override. In particolare, il valore predefinito viene segnalato se un processo esegue una query per il valore di una proprietà associata tramite la funzione di accesso al metodo Get di quella proprietà, specificando un'istanza della classe in cui sono stati definiti i metadati e il valore per quella proprietà collegata non era stato diversamente impostato.

Se si desidera abilitare l'ereditarietà del valore di una proprietà, è necessario utilizzare le proprietà associate anziché le proprietà di dipendenza non associate. Per informazioni dettagliate, vedere Ereditarietà del valore della proprietà.

Proprietà associate personalizzate

Quando creare una proprietà associata

È possibile creare una proprietà associata quando è necessario disporre di un meccanismo di impostazione delle proprietà per le classi diverse dalla classe di definizione. In questo caso, lo scenario più comune è il layout. Esempi di proprietà del layout esistenti possono essere DockPanel.Dock, Panel.ZIndex e Canvas.Top. Nello scenario abilitato in questo contesto, gli elementi che sono disponibili come elementi figlio degli elementi di controllo del layout sono in grado di indicare i requisiti del layout agli elementi padre del layout singolarmente, impostando ciascuno un valore della proprietà definito dall'elemento padre come proprietà associata.

Un altro scenario per l'utilizzo di una proprietà associata è quello in cui la classe rappresenta un servizio e si desidera che le classi siano in grado di integrare il servizio in modo più trasparente.

Infine, un ulteriore scenario prevede di ricevere un supporto Visual Studio 2008 WPF Designer, ad esempio la modifica della finestra Proprietà. Per ulteriori informazioni, vedere Cenni preliminari sulla modifica di controlli.

Come indicato in precedenza, è necessario eseguire la registrazione come proprietà associata se si desidera utilizzare l'ereditarietà del valore della proprietà.

Come creare una proprietà associata

Se la classe definisce la proprietà associata esclusivamente per l'utilizzo in altri tipi, non deve derivare da DependencyObject. Tuttavia è necessario che derivi da DependencyObject se ci si attiene al modello WPF generale che prevede che la proprietà associata sia anche una proprietà di dipendenza.

Definire la proprietà associata come proprietà di dipendenza dichiarando un campo public static readonly di tipo DependencyProperty. È possibile definire questo campo utilizzando il valore restituito dal metodo RegisterAttached. Il nome del campo deve corrispondere al nome della proprietà associata, a cui viene aggiunta la stringa Property, secondo il modello WPF stabilito per la denominazione dei campi di identificazione in base alle proprietà che rappresentano. Il provider della proprietà associata deve inoltre fornire i metodi GetNomeProprietà e SetNomeProprietà statici come funzioni di accesso per la proprietà associata; in caso di errore, il sistema di proprietà non sarà in grado di utilizzare la proprietà associata.

NotaNota

Se si omette la funzione di accesso get della proprietà associata, l'associazione dati per la proprietà non funzionerà negli strumenti di progettazione, ad esempio in Visual Studio e in Expression Blend.

Funzione di accesso Get

La firma richiesta per la funzione di accesso GetNomeProprietà è la seguente:

public static object GetPropertyName(object target)

  • L'oggetto target può essere specificato come tipo più specifico nell'implementazione. Ad esempio, il metodo DockPanel.GetDock immette il parametro come UIElement, perché si presuppone che la proprietà associata sia impostata solo nelle istanze di UIElement.

  • Il valore restituito può essere specificato come tipo più specifico nell'implementazione. Ad esempio, il metodo GetDock lo immette come Dock, dal momento che è possibile impostare tale valore solo su quell'enumerazione.

Funzione di accesso Set

La firma richiesta per la funzione di accesso SetNomeProprietà è la seguente:

public static void SetPropertyName(object target, object value)

  • L'oggetto target può essere specificato come tipo più specifico nell'implementazione. Ad esempio, il metodo SetDock lo immette come UIElement, perché si presuppone che la proprietà associata sia impostata solo nelle istanze di UIElement.

  • L'oggetto value può essere specificato come tipo più specifico nell'implementazione. Ad esempio, il metodo SetDock lo immette come Dock, dal momento che è possibile impostare tale valore solo su quell'enumerazione. Si ricordi che il valore per questo metodo è l'input proveniente dal caricatore XAML quando rileva la proprietà associata durante un utilizzo della proprietà associata nel markup. Tale input è il valore specificato come valore di un attributo XAML nel markup. Pertanto, per il tipo utilizzato devono essere disponibili la conversione di tipo, il serializzatore del valore o un supporto per l'estensione di markup, in modo da poter creare il tipo appropriato in base al valore dell'attributo, rappresentato in pratica semplicemente da una stringa.

Nell'esempio seguente viene illustrata la registrazione della proprietà di dipendenza (tramite il metodo RegisterAttached ), nonché le funzioni di accesso GetNomeProprietà e SetNomeProprietà. Nell'esempio, la proprietà associata è denominata IsBubbleSource. Pertanto, le funzioni di accesso devono essere chiamate GetIsBubbleSource e SetIsBubbleSource.

Public Shared ReadOnly IsBubbleSourceProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsBubbleSource", GetType(Boolean), GetType(AquariumObject), New FrameworkPropertyMetadata(False, FrameworkPropertyMetadataOptions.AffectsRender))
Public Shared Sub SetIsBubbleSource(ByVal element As UIElement, ByVal value As Boolean)
    element.SetValue(IsBubbleSourceProperty, value)
End Sub
Public Shared Function GetIsBubbleSource(ByVal element As UIElement) As Boolean
    Return CType(element.GetValue(IsBubbleSourceProperty), Boolean)
End Function
public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
  "IsBubbleSource",
  typeof(Boolean),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
  element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
  return (Boolean)element.GetValue(IsBubbleSourceProperty);
}

Attributi di proprietà associate

In WPF vengono definiti diversi .NET Framework attributes allo scopo di fornire informazioni sulle proprietà associate ai processi di reflection e agli utenti tipici delle informazioni sulla reflection e sulle proprietà, ad esempio i progettisti. Poiché le proprietà associate dispongono di un tipo di ambito illimitato, i progettisti devono in qualche modo evitare di confondere gli utenti con un elenco globale di tutte le proprietà associate definite in una particolare implementazione di tecnologie che utilizza XAML. Gli .NET Framework attributes specificati in WPF per le proprietà associate possono essere utilizzati per definire l'ambito di situazioni in cui una certa proprietà associata deve essere visualizzata in una finestra delle proprietà. È possibile applicare questi attributi anche per le proprietà associate personalizzate. La funzione e la sintassi degli .NET Framework attributes vengono descritti nelle relative pagine di riferimento:

Ulteriori informazioni sulle proprietà associate

  • Per ulteriori informazioni sulla creazione di una proprietà associata, vedere Procedura: registrare una proprietà associata.

  • Per scenari di utilizzo più avanzati delle proprietà di dipendenza e delle proprietà associate, vedere Proprietà Dependency personalizzate.

  • È inoltre possibile registrare una proprietà come proprietà associata e proprietà di dipendenza, ma continuare a esporre le implementazioni del "wrapper". In questo caso, la proprietà può essere impostata in quell'elemento oppure in qualsiasi elemento tramite la sintassi della proprietà associata XAML. Un esempio di proprietà con uno scenario adatto sia agli utilizzi standard, sia agli utilizzi come proprietà associata è FrameworkElement.FlowDirection.

Vedere anche

Attività

Procedura: registrare una proprietà associata

Riferimenti

DependencyProperty

Concetti

Cenni preliminari sulle proprietà di dipendenza

Proprietà Dependency personalizzate

Cenni preliminari su XAML (WPF)