WPF: attenzione ai template predefiniti

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>

Nella stessa categoria

Commenti

Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.

© 1998-2008 - Ricciolo.NET - Il blog di Cristian "Ricciolo" Civera

TagCloud
BLOG INFO
  • Post: 176
  • Commenti: 74
  • TrackBacks: 39
  • Feed blog e contenuti tecnici: RSS
  • Feed blog: RSS Atom OPML

MVP
CATEGORIE
I PIÙ LETTI DEL MESE
IN EVIDENZA