WPF: attenzione ai template predefiniti

di Cristian Civera, in .NET 3.0,

Certo, si può dormire lo stesso anche non sapendolo, ma sul nostro forum è stata posta un'interessante domanda relativa ai Content di WPF. Purtroppo la comodità di certi elementi presenti ci fa ignorare il dietro le quinte e a volte ci porta a risultati inaspettati. E' il caso delle classi ContentControl e HeaderedContentControl che dispongono delle proprietà Header e Content di tipo Object e ci consentono di fare questo:

<Button>Ciao!</Button>

Innanzitutto tramite l'interfaccia IAddChild la stringa "Ciao!" viene impostata sulla proprietà Content ed equivale quindi a scrivere:

<Button> 
    <Button.Content>Ciao!</Button.Content> 
</Button>

I vari skin applicati a Button o controlli simili, utilizzano l'oggetto ContentPresenter per includere il contenuto nel layout. Quest'oggetto applica dei template predefiniti a seconda del tipo presente in Content:

  • Se è una stringa e RecognizesAccessKey è a true, utilizza un template che crea un AccessText e con Text valorizzato con il Content stesso; altrimenti utilizza un normale TextBlock con Text valorizzato con il Content stesso;
  • Se è un UIElement, inserisce l'elemento stesso direttamente come figlio;
  • Se è un XmlNode, utilizza un TextBlock con Binding XPath = "."
  • Per gli altri restanti tipi, utilizza un TextBlock cercando di convertire prima con un TypeConverter e poi con un ToString il tipo impostato come Content.

Detto questo, quali possono essere i risultati inattesi? Prendiamo questo esempio:

<Menu> 
    <MenuItem Header="_One" /> 
    <MenuItem Header="_Two" /> 
</MenuItem>

L'uso degli underscore è riconosciuto da AccessText (il ContentPresenter del MenuItem ha RecognizesAccessKey a true) e permette l'utilizzo dello shorcut effettuando la sottolineatura della lettera che lo segue. Se usiamo però il Binding XML, per esempio, gli underscore non vengono più rinosciuti:

<MenuItem Header="{Binding XPath=/item/@text}" />

Questo perché non viene più usato il template predefinito riservato alle stringhe. Per ovviare a questo problema, occorre creare in modo esplicito l'oggetto AccessText:

<MenuItem> 
    <MenuItem.Header> 
        <AccessText Text="{Binding XPath=/item/@text}" /> 
    </MenuItem.Header> 
</MenuItem>

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese