2011-01-28 17 views
5

¿Por qué no funciona?Silverlight Defaulting ContentPresenter Contenido

En generic.xaml para un control personalizado:

En el estilo aplicado al control personalizado ...

<Setter Property="ChromeContent"> 
    <Setter.Value> 
    <Grid /> 
    </Setter.Value> 
</Setter> 

...

Más tarde, en la plantilla de control ...

<ContentPresenter Grid.Column="0" 
    x:Name="ChromeContentPresenter" 
    Content="{TemplateBinding ChromeContent}" /> 

Aquí está la dependencia pro perty para ChromeContent ...

public Object ChromeContent 
{ 
    get { return (Object)GetValue(ChromeContentProperty); } 
    set { SetValue(ChromeContentProperty, value); } 
} 
public static readonly DependencyProperty ChromeContentProperty = 
    DependencyProperty.Register("ChromeContent", typeof(Object), 
    typeof(casPopup), null); 

Como puede ver, se necesita cualquier objeto. Traté de cambiarlo a una rejilla, pero eso no ayudó.

que arroja este error (de Javascript): _Failed para asignar a la propiedad 'System.Windows.Controls.ContentPresenter.Content'

Curiosamente, la siguiente funcionará bien si quito la cuadrícula en el colocador nd solo el uso de texto:

<Setter Property="ChromeContent" Value="DEFAULT" /> 

Además, este también funcionará a partir del método OnApplyTemplate en la clase de control:

Grid g = new Grid(); 
    g.Width = 100; 
    g.Height = 25; 
    g.Background = new SolidColorBrush(Colors.LightGray); 
    ChromeContent = g; 

estoy teniendo un tiempo difícil unders indicando qué es lo que impide que funcione el contenido predeterminado de una grilla, definido en generic.xaml. ¿Alguien tiene algún conocimiento sobre este asunto?

¡Muchas gracias de antemano por su ayuda!

Respuesta

6

Este es el problema: -

<Setter Property="ChromeContent"> 
    <Setter.Value> 
    <Grid /> 
    </Setter.Value> 
</Setter> 

No debe incluir un UIElement directamente en un diccionario de recursos o como un valor de un estilo. Es posible que vea el estilo como un tipo de descriptor, pero no lo es. Los valores en un estilo son instancias construidas de los objetos que contienen. Su estilo tiene una sola instancia de Grid. Siempre que ese estilo se use para asignar a una propiedad ChromeContent, intentará asignar la misma instancia de de la cuadrícula.

A UIElement solo puede ser hijo de uno de los padres. ¿Qué pasaría si dos instancias tu control fuera construido? Habría (si Silverlight lo permite) un intento de asignar la misma instancia de la Cuadrícula a ambos controles.

Este es un motivo para las plantillas como ControlTemplate y DataTemplate. El marcado dentro de estos se invoca cada vez que se utiliza la plantilla en lugar de cuando se analiza el Xaml por primera vez.

Editar:

Para contestar la pregunta complementaria, en caso de incumplimiento otra propiedad de tipo DataTemplate: -

<Setter Property="ChromeContentTemplate"> 
    <Setter.Value> 
    <DataTemplate> 
     <Grid /> 
    </DataTemplate> 
    </Setter.Value> 
</Setter> 

propiedad: -

public Object ChromeContentTemplate 
{ 
    get { return (DataTemplate)GetValue(ChromeContentTemplateProperty); } 
    set { SetValue(ChromeContentTemplateProperty, value); } 
} 

public static readonly DependencyProperty ChromeContentTemplateProperty= 
    DependencyProperty.Register("ChromeContentTemplate", typeof(DataTemplate), 
    typeof(casPopup), null); 

plantilla de control: -

<ContentPresenter Grid.Column="0" 
    x:Name="ChromeContentPresenter" 
    Content="{TemplateBinding ChromeContent}" 
    ContentTemplate="{TemplateBinding ChromeContentTemplate" /> 
+0

Guau, muy interesante. No sabía esto. Una pregunta de seguimiento si puedo: ¿cómo podría hacer esto con la plantilla de control? Cuando intento colocar el marcado predeterminado en ContentPresenter, no puedo agregar cosas como cuadrículas y demás. Quiero que el contenido del usuario anule el mío si lo proporcionan, así que no estoy seguro de a dónde ir desde aquí. – maulkye

+0

Entendido. ¡Muchas gracias por tu ayuda! – maulkye

Cuestiones relacionadas