2009-10-12 14 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> 

me da el siguiente error:
No se puede establecer propiedades en los elementos de propiedad.WPF: No se puede establecer propiedades en los elementos de propiedad WEIRDNESS

Si utilizo:

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

Mi TextBlock muestra hasta bien, pero está anidado dentro de otro TextBlock como tal, incluso parece sumarse exterior de la propiedad Título:

<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> 

Como ya habrás adivinado, lo que me gustaría que mi código hiciera es establecer mi propiedad de Título desde XAML en un panel personalizado, si esto es posible.

También probé el mismo código con DependencyProperty en vano.

Entonces, ¿alguien que pueda ayudarme con este problema?

Respuesta

12

Puedo explicar lo que va mal y cómo solucionarlo.

En primer lugar,

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

es un simple error de sintaxis. La sintaxis <l:CustomPanel.Caption> no acepta atributos XML; el valor de la propiedad debe estar dentro del elemento.

Esta es la sintaxis de elementos de propiedad adecuada:

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

pero:

  1. sintaxis de elementos de propiedad funciona sólo con DependencyProperties (por lo que no funcionó con su propiedad CLR) y
  2. Propiedad la sintaxis del elemento siempre respeta ContentPropertyAttribute del tipo de propiedad

Dado que TextBlock tiene un [ContentPropertyAttribute ("Inlines")], la sintaxis del elemento de propiedad está intentando agregar el TextBlock a la colección Inlines.

La solución es simple: declare su propiedad como una propiedad de dependencia del tipo UIElement en lugar de tipo TextBlock. Esto tiene la ventaja adicional de no restringir la visualización de contenido a solo un TextBlock. Si realmente desea restringirlo a un TextBlock, puede usar una devolución de llamada de validación.

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

Thx Ray, que trabajaba :) A pesar de que no lo necesitaba más, puede ser que se necesitará en el futuro, sin embargo, así que gracias para la explicación clara. – Willy

+0

Excepto, ¿cómo se supone que debes decir ? Alguien no pensó en esto y lo aplicó ciegamente a * todos * atributos, incluso aquellos que no les pertenecen. –

2

Acabo de recibir una solución no ideal de un colega mío. Se trata de declarar la propiedad de título como un recurso como:

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

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

todavía me gustaría saber por qué no puedo usar las dos opciones anteriores, así que si alguien sabe por favor responda. :)

0

Parece que usted puede conseguir este error (en Silverlight 4 y 5 por lo menos) si se especifica un espacio de nombres en el elemento.Por ejemplo:

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

En este caso MapLayer.Position es una propiedad adjunta. Parece que el analizador Silverlight requiere el espacio de nombres que se definen utilizando un prefijo:

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