2011-01-28 10 views
5

Perché non funziona?Silverlight Contenuto predefinito Contenuto Presentatore

In generic.xaml per un controllo personalizzato:

Nello stile applicato al controllo personalizzato ...

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

...

Più tardi, nel modello di controllo ...

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

Ecco la dipendenza pro perty per 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); 

Come puoi vedere, prende qualsiasi oggetto. Ho provato a cambiarlo in una griglia, ma questo non ha aiutato.

getta questo errore (da javascript): _Failed da assegnare alla proprietà 'System.Windows.Controls.ContentPresenter.Content'

Stranamente, il seguente funziona bene se mi tolgo la griglia dal setter appena nd uso di testo:

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

Inoltre, questo funzionerà anche dal metodo OnApplyTemplate nella classe di controllo:

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

sto avendo un duro under tempo tanding ciò che impedisce il contenuto predefinito di una griglia, definito in generic.xaml dal lavoro. Qualcuno ha qualche conoscenza su questo argomento?

Molte grazie in anticipo per il vostro aiuto!

risposta

6

Questo è il problema: -

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

non si dovrebbe includere un UIElement direttamente in un dizionario risorse o come valore di uno stile. Potresti vedere lo stile come una sorta di descrittore, ma non lo è. I valori in uno stile sono istanze costruite degli oggetti che contengono. Il tuo stile contiene una singola istanza di Grid. Ogni volta che lo stile viene utilizzato per assegnare a una proprietà ChromeContent, tenterà di assegnare la stessa istanza singola di della griglia.

A UIElement può essere solo un figlio di un genitore. Cosa succederebbe se due istanze del tuo controllo fossero state costruite? Ci sarebbe (se Silverlight ti lascia) un tentativo di assegnare la stessa istanza singola della griglia a entrambi i controlli.

Questo è uno dei motivi per modelli come ControlTemplate e DataTemplate. La marcatura all'interno di questi viene invocata ogni volta che viene utilizzato il modello piuttosto che quando Xaml viene analizzato per la prima volta.

Edit:

di rispondergli domanda supplementare, si dovrebbe di default un'altra proprietà di tipo DataTemplate: -

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

Proprietà: -

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

modello di controllo: -

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

Wow, molto interessante. Non lo sapevo Una domanda di follow-up se posso: come farei questo con il modello di controllo? Quando tento di inserire il markup di default in ContentPresenter, non posso aggiungere cose come griglie o altro. Voglio che il contenuto dell'utente sostituisca il mio se lo fornisce, quindi non sono sicuro di dove andare da qui. – maulkye

+0

Capito. Grazie mille per il vostro aiuto! – maulkye

Problemi correlati