2017-06-20 3 views
0

So habe ich einen Stil, unten, den ich auf mehrere Schaltflächen in meinem Formular (WPF) anwenden möchte. Aber jede Schaltfläche muss eine andere Beschriftung haben, und ich kann nicht den gleichen Stil auf jede anwenden, ohne für jede einzelne + Kopieren + Einfügen + Umbenennen zu kopieren (und den Inhalt im Textblock zu setzen).Wie definiere ich einen benutzerdefinierten Stil für eine Schaltfläche, aber unterschiedliche Text-/Inhaltsanzeige für jede Schaltfläche?

XAML in App.xaml

<Style x:Key="RunReportButton" 
       TargetType="{x:Type Button}" 
       BasedOn="{StaticResource {x:Type Button}}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Grid Background="#EEB4B4"> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualState x:Name="Normal" /> 
           <VisualState x:Name="MouseOver"> 
            <Storyboard> 
             <ColorAnimation Storyboard.TargetName="ButtonBorder" 
                  Storyboard.TargetProperty="Color" 
                  To="#d6a2a2" 
                  Duration="0:0:00.0" /> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Pressed"> 
            <Storyboard> 
             <ColorAnimation Storyboard.TargetName="ButtonBorder" 
             Storyboard.TargetProperty="Color" 
             To="#d6a2a2" 
             Duration="0:0:00.0" /> 
            </Storyboard> 
           </VisualState> 
          </VisualStateGroup> 
         </VisualStateManager.VisualStateGroups> 
         <Border> 
          <Border.Background> 
           <SolidColorBrush x:Name="ButtonBorder" 
           Color="Transparent" /> 
          </Border.Background> 
         </Border> 
         <TextBlock 
            FontFamily="Open Sans" 
            FontSize="16" 
            FontWeight="SemiBold" 
            Foreground="#CD3333" 
            HorizontalAlignment="Center" 
            VerticalAlignment="Center" 
            Margin="5,5,5,5"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

in meiner Form Bindung:

<Button Style="{StaticResource RunReportButton}" 
        Margin="0,20"/> 
+1

Verwenden Sie 'ContentPresenter' anstelle von' TextBlock' in der Vorlage und legen Sie 'FontFamily' usw. über Stil-Setter fest – ASh

Antwort

0

Verwenden Sie anstelle der TextBlock in der ControlTemplate eine ContentPresenter. Standardmäßig wird die Content Eigenschaft des Vorlagen-Elternteils angezeigt - der Button in Ihrem Fall. Sie könnten eine andere Eigenschaft des übergeordneten Templates angeben, indem Sie ContentPresenter.ContentSource festlegen, aber in diesem Fall ist der Standardwert korrekt.

A TextBlock ist eine schlechte Wahl für diese Rolle, weil alle sie angezeigt werden kann ein String ist, aber Button.Content könnte alles sein - ein Image, ein DataGrid, ein Ansichtsmodell, alles. Kein Grund, diese Fülle von Möglichkeiten nicht zu bewahren.

Es gab einen Fehler in Ihrer ursprünglichen Vorlage: <ControlTemplate> fehlte TargetType="Button", die für die ordnungsgemäße Funktion der Vorlage kritisch ist.

<Style 
    x:Key="RunReportButton" 
    TargetType="{x:Type Button}" 
    BasedOn="{StaticResource {x:Type Button}}" 
    > 
    <Setter Property="TextElement.FontFamily" Value="Open Sans" /> 
    <Setter Property="HorizontalContentAlignment" Value="Center" /> 
    <Setter Property="VerticalContentAlignment" Value="Center" /> 
    <Setter Property="Background" Value="#EEB4B4" /> 
    <!-- Ditto for other TextElement.FontSize etc. --> 

    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="Button"> 
       <Grid Background="{TemplateBinding Background}"> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Normal" /> 
          <VisualState x:Name="MouseOver"> 
           <Storyboard> 
            <ColorAnimation Storyboard.TargetName="ButtonBorder" 
                Storyboard.TargetProperty="Color" 
                To="#d6a2a2" 
                Duration="0:0:00.0" /> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Pressed"> 
           <Storyboard> 
            <ColorAnimation 
             Storyboard.TargetName="ButtonBorder" 
             Storyboard.TargetProperty="Color" 
             To="#d6a2a2" 
             Duration="0:0:00.0" /> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Border> 
         <Border.Background> 
          <SolidColorBrush x:Name="ButtonBorder" 
         Color="Transparent" /> 
         </Border.Background> 
        </Border> 
        <!-- Ditto for other TextElement.FontSize etc. --> 
        <ContentPresenter 
         TextElement.FontFamily="{TemplateBinding TextElement.FontFamily}" 
         HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
         VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
         Margin="5,5,5,5" 
         /> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Auch wenn Sie TemplateBindings verwenden, wie gezeigt, können Sie Standardwerte für diese Eigenschaften in Ihrem Button-Stil, und lassen Sie die Verbraucher sie in der XAML außer Kraft setzen, wenn er will.

+0

Ich mag diesen Ansatz am meisten ... aber ich lasse den Inhalt immer noch nicht erscheinen, außer ich definiere explizit die Content-Eigenschaft im Stil –

+0

Wie gibst du dem Button seinen Inhalt? –

+0

Ich wollte es nur im XAML des Fensters selbst setzen. –

0
  1. Für jede Taste, stellen Sie die Content Eigenschaft auf, was Text Sie wollen.
  2. Setzen Sie die TextBlockText Eigenschaft auf {TemplateBinding Content}. Diese Markup-Erweiterung bindet unidirektional an die angegebene DependencyProperty des Elements, zu dem die ControlTemplate gehört.
+0

So kann ich die Text-Eigenschaft des TextBlocks nicht auf diese setzen, weil der" Element-Inhalt nicht erkannt oder nicht zugreifbar "ist. Habe ich die DependencyProperty nicht entsprechend eingestellt? –

+0

@MichaelHolvey * "" Mitglieder-Inhalt wird nicht erkannt oder ist nicht zugänglich "" * wäre aufgrund des fehlenden TargetTypes entstanden. Alles ist jetzt klar! –

Verwandte Themen