2009-08-29 10 views
15

Je suis en train de faire quelque chose comme ça ...Est-ce que mon Setter Style WPF peut utiliser un TemplateBinding?

<Style 
    x:Key="MyBorderStyle" 
    TargetType="Border"> 
    <Setter 
     Property="BorderBrush" 
     Value="{StaticResource MyBorderBrush}" /> 
    <Setter 
     Property="Background" 
     Value="{StaticResource MyBackgroundBrush}" /> 
    <Setter 
     Property="Padding" 
     Value="{TemplateBinding Padding}" /> 
</Style> 

... mais je reçois l'erreur: 'Padding' member is not valid because it does not have a qualifying type name.

Comment puis-je fournir un « nom de type admissible »?

Remarque: La raison pour laquelle j'essaie de le faire est que je souhaite inclure la même bordure dans une série de ControlTemplates similaires.

Merci.

EDIT:

Eh bien, j'ai essayé ça ...

<Setter 
    Property="Padding" 
    Value="{TemplateBinding GridViewColumnHeader.Padding}" /> 

... et effectivement compilé, mais quand je courais l'application, je suis un XamlParseException:

Cannot convert the value in attribute 'Value' to object of type ''.

Je pensais peut-être qualifier Padding avec GridViewColumnHeader (qui est le ControlTemplate je veux utiliser ce style avec) fonctionnerait, mais pas de dés.

EDIT 2:

Eh bien, selon la documentation TemplateBinding, il est dit:

Links the value of a property in a control template to be the value of some other exposed property on the templated control.

Il semble donc que ce que je suis en train de faire est tout simplement impossible. Je voudrais vraiment pouvoir créer des styles réutilisables pour certains contrôles dans mes modèles de contrôle, mais je suppose que les liaisons de modèles ne peuvent pas être incluses dans ces styles.

Répondre

31

Cela devrait fonctionner dans le cas où vous êtes en train de modéliser un contrôle et que vous voulez lier la valeur d'une propriété de ce contrôle à une propriété d'un autre contrôle dans le modèle. Dans votre cas, vous êtes en train de modéliser quelque chose (appelez-le MyControl), et ce modèle inclura une bordure dont le remplissage doit être lié au remplissage de MyControl.

De MSDN documentation:

A TemplateBinding is an optimized form of a Binding for template scenarios, analogous to a Binding constructed with {Binding RelativeSource={RelativeSource TemplatedParent}}.

Pour une raison quelconque, en spécifiant TemplatedParent comme source pour la liaison ne semble pas fonctionner au sein de style Setters. Pour contourner cela, vous pouvez spécifier le parent relatif comme AncestorType du contrôle que vous êtes en train de modéliser (qui trouve effectivement le TemplatedParent à condition que vous n'ayez pas incorporé d'autres MyControls dans le modèle MyControl).

J'ai utilisé cette solution lorsque j'essayais de personnaliser le modèle d'un contrôle Button dans lequel le contenu (String) du bouton devait être lié à la propriété Text d'un TextBlock dans ControlTemplate pour le bouton.Voici à quoi ressemblait ce code:

<StackPanel> 
    <StackPanel.Resources> 
     <ControlTemplate x:Key="BarButton" TargetType="{x:Type Button}"> 
      <ControlTemplate.Resources> 
       <Style TargetType="TextBlock" x:Key="ButtonLabel"> 
        <Setter Property="Text" Value="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type Button}} }" /> 
       </Style> 
      </ControlTemplate.Resources> 
      <Grid> 
       <!-- Other controls here --> 
       <TextBlock Name="LabelText" Style="{StaticResource ButtonLabel}" /> 
      </Grid> 
     </ControlTemplate> 
    </StackPanel.Resources> 
    <Button Width="100" Content="Label Text Here" Template="{StaticResource BarButton}" /> 
</StackPanel> 
+0

Bonne idée, Shane. Merci. – devuxer

3

Une propriété peut être qualifiée simplement en la préfixant avec le nom du type. Par exemple, Border.Padding au lieu de Padding. Cependant, je ne suis pas sûr que ce soit logique pour votre scénario. TemplateBinding s sont utilisés à l'intérieur d'un modèle de contrôle.

+1

Merci, @Kent. Votre réponse m'a donné une idée pour essayer (voir mon édition ci-dessus), mais cela n'a pas fonctionné. Il est logique que 'TemplateBinding's ne peut être utilisé dans un ControlTemplate ... si seulement je pouvais convaincre l'analyseur que j'ai l'intention d'utiliser ce style uniquement dans un ControlTemplate ... – devuxer

Questions connexes