2011-01-28 5 views
5

Почему это не будет работать?Silverlight Defaulting ContentPresenter Content

В Generic.xaml для таможенного контроля:

В стиле применительно к таможенному контролю ...

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

...

Позже, в шаблоне управления ...

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

Вот депеша ndency для 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); 

Как вы можете видеть, требуется любой объект. Я попытался изменить его на грид, но это не помогло.

Он выдает эту ошибку (от JavaScript): _Failed присвоить свойству «System.Windows.Controls.ContentPresenter.Content»

Как ни странно, следующий будет работать нормально, если я удалить сетку из сеттера Н.Д. просто использовать текст:

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

Кроме того, это тоже будет работать с OnApplyTemplate метода в классе управления:

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

Я с трудом понимаю что предотвращает использование по умолчанию содержимого сетки, определяемое в generic.xaml от работы. Кто-нибудь знает об этом?

Большое спасибо за вашу помощь!

ответ

6

Это проблема: -

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

Вы не должны включать в себя UIElement непосредственно в словаре ресурсов или как значение стиля. Вы можете видеть стиль как своего рода дескриптор, но это не так. Значения в стиле создаются экземплярами объектов, которые они хранят. В вашем стиле содержится один экземпляр Grid. Всякий раз, когда этот стиль используется для назначения объекту ChromeContent, он попытается воспроизвести один и тот же экземпляр Grid.

A UIElement может быть только ребенком одного родителя. Что произойдет, если будут созданы два экземпляра вашего контроля? Было бы (если позволит Silverlight) попытаться присвоить один и тот же экземпляр Grid для обоих элементов управления.

Это одна из причин для шаблонов, таких как ControlTemplate и DataTemplate. Разметка внутри них вызывается каждый раз, когда используется шаблон, а не когда сначала разбирается Xaml.

Edit:

Чтобы ответить вам дополнительный вопрос, вы должны по умолчанию другое свойство типа DataTemplate: -

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

недвижимости: -

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

управления Шаблон: -

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

Ничего себе, очень интересно. Я этого не знал. Последующий вопрос, если я могу: Как мне сделать это с помощью шаблона управления? Когда я пытаюсь разместить разметку по умолчанию в ContentPresenter, я не могу добавлять такие вещи, как сетки и т. Д. Я хочу, чтобы контент пользователя переопределял мой, если они его предоставляют, поэтому я не уверен, куда идти отсюда. – maulkye

+0

Понял. Большое вам спасибо за вашу помощь! – maulkye

 Смежные вопросы

  • Нет связанных вопросов^_^