2009-10-12 4 views
10
private TextBlock _caption = new TextBlock(); 

public TextBlock Caption 
{ 
    get { return _caption; } 
    set { _caption = value; } 
} 

<l:CustomPanel> 
    <l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" /> 
</l:CustomPanel> 

mi dà il seguente errore:
Impossibile impostare le proprietà su elementi di proprietà.WPF: proprietà non può impostare su elementi di proprietà stranezza

Se uso:

<l:CustomPanel> 
    <l:CustomPanel.Caption> 
     <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> 
    </l:CustomPanel.Caption> 
</l:CustomPanel> 

mio TextBlock si presenta bene ma è nidificato all'interno di un altro TextBlock in questo modo, sembra anche di aggiungere se stessa al di fuori della proprietà Caption:

<l:CustomPanel> 
    <l:CustomPanel.Caption> 
     <TextBlock> 
      <InlineUIContainer> 
       <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> 
      </InlineUIContainer> 
     </TextBlock> 
    </l:CustomPanel.Caption> 

    <TextBlock> 
     <InlineUIContainer> 
      <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> 
     </InlineUIContainer> 
    </TextBlock> 
</l:CustomPanel> 

Come avresti già potuto indovinare, quello che vorrei che il mio codice fosse fare è impostare la mia proprietà Caption da XAML su un pannello personalizzato, se possibile.

Ho anche provato lo stesso codice con DependencyProperty senza alcun risultato.

Quindi, chiunque mi può aiutare con questo problema?

risposta

12

Posso spiegare cosa sta andando storto e come risolverlo.

In primo luogo,

<l:CustomPanel> 
    <l:CustomPanel.Caption Text="Caption text" FontSize="18" Foreground="White" /> 

è un semplice errore di sintassi. La sintassi <l:CustomPanel.Caption> non accetta attributi XML: il valore della proprietà deve essere all'interno dell'elemento.

Questo è elemento proprio immobile sintassi:

<l:CustomPanel>  
    <l:CustomPanel.Caption> 
    <TextBlock Text="Caption text" FontSize="18" Foreground="White" /> 
    </l:CustomPanel.Caption> 
</l:CustomPanel> 

ma:

  1. proprietà Sintassi elemento funziona solo con DependencyProperties (in modo che non ha funzionato con la vostra proprietà CLR) e
  2. Proprietà la sintassi dell'elemento onora sempre il ContentPropertyAttribute del tipo di proprietà

Poiché TextBlock ha un [ContentPropertyAttribute ("Inlines")], la sintassi dell'elemento property sta tentando di aggiungere TextBlock alla raccolta Inlines.

La soluzione è semplice: dichiarare la vostra proprietà come DependencyProperty di tipo UIElement invece di tipo TextBlock. Questo ha l'ulteriore vantaggio di non limitare la visualizzazione del contenuto solo a un TextBlock. Se vuoi davvero limitarlo a un solo TextBlock, puoi usare un callback di convalida.

public UIElement Content { get { ... 
public static readonly DependencyProperty ContentProperty = ... 
+0

Thx Ray, che ha funzionato :) Anche se non ho più bisogno, potrei avere bisogno in futuro, però, quindi grazie per la chiara spiegazione – Willy

+0

Tranne, come dovresti dire ? Qualcuno non ci ha pensato e ha applicato ciecamente questo a * tutti * gli attributi, anche quelli che non appartengono a loro. –

2

Ho appena ottenuto una soluzione non ideale da un mio collega. Coinvolge dichiarando la proprietà Caption come una risorsa come:

<Page.Resources> 
    <TextBlock x:Key="test" Text="Caption text" FontSize="18" Foreground="White" /> 
</Page.Resources> 

<l:CustomPanel Caption="{StaticResource test}" /> 

mi piace ancora di sapere il motivo per cui non posso usare le due opzioni precedenti, quindi se qualcuno sa prega di rispondere. :)

0

Sembra che si può ottenere questo errore (in Silverlight 4 e 5 almeno) se si specifica uno spazio dei nomi sull'elemento.Ad esempio:

<Path> 
    <MapLayer.Position xmlns="clr-namespace:Microsoft.Maps.MapControl"> 
     ... 

In questo caso MapLayer.Position è una proprietà associata. Sembra che il parser Silverlight richiede lo spazio dei nomi da definire con un prefisso:

<Path xmlns:map="clr-namespace:Microsoft.Maps.MapControl"> 
    <map:MapLayer.Position> 
     ...