Подчеркните неявный Textblock, созданный в Silverlight для ContentPresenter, когда Content является строкой? - PullRequest
1 голос
/ 12 августа 2010

Я пытаюсь создать шаблон для элемента управления содержимым, такого как Button или HeaderedContentControl и т. Д., Где текст подчеркнут.

Я просто хочу подчеркнуть текст, когда указан Content="This text is underlined".

Он должен продолжать работать в обычном режиме, если Content является другим элементом UIElement.

Большинство постов, задающих этот же вопрос, удовлетворены изменением шаблона для работы только для строки в качестве содержимого.У Скотта Гу есть хорошая статья о кнопках стиля , но он не решает эту проблему.

Следующий пример будет работать, если вы фактически передадите Content как экземпляр типа TextBlockно не как строка.Конечно, визуальное дерево имеет TextBlock, поэтому оно должно его стилизовать.Возможно, это ограничение Sivlerlight.

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

    <navigation:Page.Resources>
    <Style TargetType="TextBlock" x:Key="style123">
        <Setter Property="Foreground"  Value="Red"/>
        <Setter Property="FontSize" Value="72"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="TextDecorations" Value="Underline"/>
    </Style>
</navigation:Page.Resources>

<StackPanel>        

    <!-- This doesn't work and shows black text -->
    <ContentPresenter Content="Small black text">
        <ContentPresenter.Resources>
            <Style TargetType="TextBlock" BasedOn="{StaticResource style123}"/>
        </ContentPresenter.Resources>
    </ContentPresenter>

    <!-- This works and shows red text -->
    <ContentPresenter>
        <ContentPresenter.Content>
            <TextBlock Text="This is big red text"/>
        </ContentPresenter.Content>

        <ContentPresenter.Resources>
            <Style TargetType="TextBlock" BasedOn="{StaticResource style123}"/>
        </ContentPresenter.Resources>
    </ContentPresenter>

</StackPanel>

Ответы [ 2 ]

1 голос
/ 12 августа 2010

Вы можете создать подкласс любого фактического ContentControl (т.е. Button), который вы используете, и переопределить OnContentChanged, чтобы сбросить свойство Content в подчеркнутое TextBlock, если newContent - строка. В случае если newContent не является строкой, он будет работать обычным способом.

public class UnderlineButton : Button
{
    protected override void OnContentChanged(object oldContent, object newContent)
    {
        if (newContent is string)
        {
            TextBlock textBlock = new TextBlock();
            textBlock.Text = newContent as string;
            textBlock.TextDecorations = TextDecorations.Underline;
            this.Content = textBlock;
        }

        base.OnContentChanged(oldContent, newContent);
    }
}

Раздражать подклассы довольно просто для достижения этой цели, но избегать грязных шаблонов стилей и подклассов ContentPresenter.

0 голосов
/ 12 августа 2010

Попробуйте этот пример, используя DataTemplate для пользовательского рендеринга string содержимого (я только что установил красный фон):

<ContentControl Content="{Binding YourData}" >
  <ContentControl.Resources>
    <DataTemplate DataType="{x:Type s:String}">
      <TextBlock Text="{Binding}" Background="Red" />
    </DataTemplate>
  </ContentControl.Resources>
</ContentControl>

РЕДАКТИРОВАТЬ: просто как примечание, вы можете использовать его в стиле ContentControl, вместо того, чтобы применять его каждый раз, если вам требуется лучшая возможность повторного использования ...

...