2010-08-11 51 views
1

我正在嘗試爲內容控件(如Button或HeaderedContentControl等)創建一個模板,其中文本帶下劃線。當Content是字符串時,爲Silverlight中的ContentPresenter下劃線隱式文本塊?

我只想在指定Content="This text is underlined"時加下劃線。

如果Content是另一個UIElement,它必須繼續正常工作。

提問這個問題的大多數帖子都滿意,修改模板只能用於字符串作爲內容。 Scott Gu有一篇關於styling buttons的好文章,但沒有解決這個問題。

如果您實際通過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> 
+0

PS。我很好,如果解決方案是像ContentPresenter的子類和攔截事件或類似的東西瘋狂。嗯,我只是意識到也許這可能會工作... – 2010-08-11 23:53:21

+0

瘋狂的解決方案很少需要在WPF - 看到我的答案;-) – 2010-08-12 15:49:05

回答

1

你可以繼承任何實際ContentControl您正在使用,並以該Content屬性重置爲帶下劃線的TextBlock如果newContent是一個字符串覆蓋OnContentChanged(即Button)。在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

謝謝!這不需要是base.OCC()的其他條件嗎? – 2010-08-12 18:19:29

+0

我不這麼認爲,你總是想要通知內容更改的基本控制。在newContent是一個字符串的情況下,您只需「跳入」並首先切換實際內容。 – 2010-08-13 15:45:38

+0

啊,這是正確的...這是OnContentChanged而不是OnContentChanging(它可能不會實際退出 - 我沒有檢查)。看起來像這個解決方案是現在最好的Silverlight! – 2010-08-16 21:36:42

0

試試這個例子中,使用一個DataTemplate定製渲染string內容(我剛剛將背景設置爲紅色):

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

編輯:就像一個音符,你可以拉了這一點成ContentControl風格,而不是每次應用它內聯,如果您需要更好的可重用性...

+0

我確實嘗試過這樣的工作,但無法使用silverlight工作。我知道這是Silverlight中的WPF cos,我們甚至沒有TextBlock的背景! :-( – 2010-08-12 18:17:34

+0

那麼你是否終於開始工作?你的解決方案是什麼? – 2010-10-27 16:52:08