2013-03-26 62 views
1

我們想要設置一個wpf按鈕,以便按鈕中設置的內容顯示兩次。原因是我們想要實現按鈕內容的陰影效果。出來的想法是有在按鈕二類花ContentControls象下面這樣:在WPF按鈕中顯示相同的內容兩次

<ContentControl x:Name="ContentControl" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> 
<ContentControl Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Foreground="White" Margin="0,1,0,0" /> 

所以,一個ContentControl中用於顯示真正的內容和一個ContentControl中是如此,它給人的效果顯示與一個小保證金相同的內容作爲陰影。問題在於它不會在兩個內容控件中顯示內容。其中只有一個顯示內容。我如何在兩個內容控件中成功顯示內容?

此外,由於按鈕的內容變得模糊,因此不能選擇陰影效果。

感謝您的幫助!

+0

第二個ContentControl沒有ContentTemplate綁定,你也應該總是綁定ContentTemplateSelector,相信我,這會爲你節省很多惱人的bug。另外,您應該閱讀ContentPresenter及其在ContentControls中的使用。 – dowhilefor 2013-03-26 12:11:36

+0

感謝您的回覆。我知道在模板中使用ContentPresenter和ContentControl存在差異。我在這裏使用contentControl的原因是能夠設置contentControl的Foreground屬性。這樣我可以控制前景取決於VisualState(按下按鈕等)。 ContentPresenter沒有前景屬性。 ContentTemplate沒有任何區別,使用2個ContentPresenter也沒有幫助。 – exkoria 2013-03-26 12:25:31

回答

1

按鈕使用嵌套內容

<Style x:Key="ShadowButton" 
     TargetType="{x:Type Button}"> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type Button}"> 
     <Grid> 
      <Rectangle Width="{Binding ActualWidth, 
             ElementName=presenter}" 
         Height="{Binding ActualHeight, 
             ElementName=presenter}"> 
      <Rectangle.Fill> 
       <VisualBrush AlignmentX="Left" 
          Stretch="None" 
          Visual="{Binding ElementName=presenter}" /> 
      </Rectangle.Fill> 
      <Rectangle.RenderTransform> 
       <TranslateTransform X="3" 
            Y="3" /> 
      </Rectangle.RenderTransform> 
      </Rectangle> 
      <!-- You can replace the following line to a ContentControl if you absolutely have to --> 
      <ContentPresenter x:Name="presenter" 
          ContentSource="Content" /> 
     </Grid> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

使用就可以是動態的,如:

<Button HorizontalAlignment="Center" 
     VerticalAlignment="Center" 
     FontSize="36" 
     Style="{StaticResource ShadowButton}"> 
    <StackPanel> 
    <Button Margin="2" 
      Content="A" /> 
    <Button Margin="2" 
      Content="B" /> 
    <TextBox Margin="2" 
      Text="Blah" /> 
    </StackPanel> 
</Button> 

通過使用VisualBrush你不能在你的風格2 ContentControl/ContentPresenter和只是渲染一個填入一個Brush以填充矩形並獲得您的效果。

複製視覺樹模板

嘗試有一個UserControl這樣做比在首位Button。如果您想在樣式中複製可視化樹,則需要使用模板。

<Style x:Key="ShadowButton" 
     TargetType="{x:Type Button}"> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type Button}"> 
     <Grid> 
      <ContentControl x:Name="shadow" 
          ContentTemplate="{TemplateBinding ContentTemplate}" 
          Foreground="SpringGreen"> 
      <ContentControl.RenderTransform> 
       <TranslateTransform X="50" 
            Y="50" /> 
      </ContentControl.RenderTransform> 
      </ContentControl> 
      <ContentControl x:Name="presenter" 
          ContentTemplate="{TemplateBinding ContentTemplate}" 
          Foreground="SlateBlue" /> 
     </Grid> 
     <ControlTemplate.Triggers> 
      <Trigger SourceName="presenter" 
        Property="IsMouseOver" 
        Value="True"> 
      <Setter TargetName="shadow" 
        Property="Foreground" 
        Value="Teal" /> 
      <Setter TargetName="presenter" 
        Property="Foreground" 
        Value="Red" /> 
      </Trigger> 
     </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

與用法:

<Button HorizontalAlignment="Center" 
     VerticalAlignment="Center" 
     Style="{StaticResource ShadowButton}"> 
    <Button.ContentTemplate> 
    <DataTemplate> 
     <StackPanel> 
     <Button Margin="2" 
       Content="A" 
       Foreground="{Binding RelativeSource={RelativeSource FindAncestor, 
                    AncestorType={x:Type ContentControl}}, 
             Path=Foreground}" /> 
     <TextBox Margin="2" 
        Foreground="{Binding RelativeSource={RelativeSource FindAncestor, 
                     AncestorType={x:Type ContentControl}}, 
             Path=Foreground}" 
        Text="Blah" /> 
     </StackPanel> 
    </DataTemplate> 
    </Button.ContentTemplate> 
</Button> 
+0

像這樣更改模板將刪除選項以將其用於自定義數據,因爲現在缺少ContentPresenter。雖然我明白這是爲了解釋,但應該指出,這不是一個好的做法。 – dowhilefor 2013-03-26 12:13:21

+0

我使用ContentControl而不是ContentPresenter,因爲我需要根據視覺狀態更改Button的內容的Foreground。如果按鈕的內容僅爲文本,則您的解決方案將起作用。然而,如果你在按鈕的內容中有自定義內容(例如一個具有多個子元素的堆疊面板),它將不起作用 – exkoria 2013-03-26 12:28:59

+0

@dowhilefor是的,這個樣式發佈將只針對只有文字內容的按鈕用於陰影效果。它不缺少ContentPresenter tho(它仍然在樣式中使用它),只有效果被綁定到ContentPresenter的Text屬性,如果該按鈕持有其他子元素並且具有此樣式,則不起作用。更新答案以適應任何嵌套的子控件。 – Viv 2013-03-26 14:29:17

0

我在一個小的虛擬應用程序嘗試這樣做,它工作得很好。看看這是你想要的。

 <Window.Resources> 
     <Style x:Key="test" TargetType="Button"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Button}"> 
         <Grid> 
          <ContentControl Content="{TemplateBinding Content}" 
              ContentTemplate="{TemplateBinding ContentTemplate}" 
              ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"/> 
          <ContentControl Foreground="DarkGray" 
              Content="{TemplateBinding Content}" 
              ContentTemplate="{TemplateBinding ContentTemplate}" 
              ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"> 
           <ContentControl.RenderTransform> 
            <TranslateTransform Y="2" X="2"/> 
           </ContentControl.RenderTransform> 
          </ContentControl> 
         </Grid> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <Button Style="{StaticResource test}"> 
      Test 
     </Button> 
    </Grid> 
+0

感謝您的回覆。不,它不起作用。它適用於只是字符串內容而不是複雜的內容,如 <按鈕樣式=「{StaticResource的測試}」> exkoria 2013-03-27 15:46:12

+0

以及有沒有簡單的方法來解決這個問題的話,現在最好的方法是利用VisualBrush實現陰影效果,同時只保留一個內容。 – dowhilefor 2013-03-27 15:51:56