2010-06-30 5 views
1

J'ai un style simple pour les contrôles d'étiquette. Je voudrais définir un modèle de contrôle à l'intérieur du style avec un bouton, qui pourrait être cliqué et définirait la propriété de visibilité de l'étiquette à 'caché'. Quelque chose comme ceci:Comment référencer le contrôle parent à partir d'un style ControlTemplate dans WPF?

<Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Label}"> 
       <Border BorderThickness="1" Padding="4" CornerRadius="3" 
         BorderBrush="Gray" Background="#FFA11616"> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="*" /> 
          <ColumnDefinition Width="Auto" /> 
         </Grid.ColumnDefinitions> 
         <ContentPresenter Grid.Column="0"/> 
         <Button Grid.Column="1" Width="16" Height="16" Padding="2" FontSize="9" Content="X"> 
         <!-- THIS IS WRONG! HOW TO CREATE A TRIGGER FOR THIS BUTTON 
          HERE AND HOW TO REFER TO THE LABEL? --> 
          <Button.Triggers> 

           <Trigger Property="Button.IsPressed" Value="True"> 
            <Setter Property="Visibility" Value="Hidden" /> 
           </Trigger> 
          </Button.Triggers> 
         </Button> 
        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Le problème est que je ne suis pas sûr de savoir comment gérer le clic avec un déclencheur et aussi comment définir une propriété de l'étiquette contenant le bouton.

Merci.

Répondre

1

Vous pouvez utiliser un ToggleButton au lieu du bouton normal et puis il suffit d'utiliser la propriété IsChecked pour le déclencheur:

<Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Label}"> 
       <Border BorderThickness="1" Padding="4" CornerRadius="3" 
       BorderBrush="Gray" Background="#FFA11616"> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="*" /> 
          <ColumnDefinition Width="Auto" /> 
         </Grid.ColumnDefinitions> 
         <ContentPresenter Grid.Column="0"/> 
         <ToggleButton x:Name="CloseButton" Grid.Column="1" Width="16" Height="16" Padding="2" FontSize="9" Content="X"/> 
        </Grid> 
       </Border> 
       <ControlTemplate.Triggers> 
        <Trigger SourceName="CloseButton" Property="IsChecked" Value="True"> 
         <Setter Property="Visibility" Value="Hidden" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
2

J'authored avec ce mélange 4. Essentiellement, vous voulez gérer l'événement « PreviewMouseButtonUp » sur votre bouton avec une EventTrigger. Le EventTrigger va démarrer un Storyboard qui anime la propriété UIElement.Visibility à "Caché" en haut de l'arbre visuel pour le style de votre étiquette.

Pour obtenir le contrôle sur le contenu du bouton, vous pouvez utiliser la propriété Tag sur le contrôle de l'étiquette. Sinon, vous devrez créer une autre propriété de dépendance, ce qui signifie sous-classer Label.

A l'intérieur du style, puis, le <Button/> ressemble à ceci:

<Button x:Name="button" Grid.Column="1" Padding="2" 
    FontSize="9" 
    Content="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"/> 

... et puisque vous pouvez mettre quoi que ce soit dans une propriété Tag vous pouvez le faire:

<Label x:Name="label" Content="Label" 
     Style="{DynamicResource MessageLabel_WithCloseButton}"> 
     <Label.Tag> 
      <StackPanel> 
       <TextBlock>WOOT</TextBlock> 
       <TextBlock>WOOT</TextBlock> 
      </StackPanel> 
     </Label.Tag> 
    </Label> 

Voici un style complet modifié (j'ai également modifié certaines choses pour un meilleur dimensionnement automatique:

<Style x:Key="MessageLabel_WithCloseButton" TargetType="{x:Type Label}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Label}"> 
        <ControlTemplate.Resources> 
         <Storyboard x:Key="OnClick1"> 
          <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="border"> 
           <DiscreteObjectKeyFrame KeyTime="0"> 
            <DiscreteObjectKeyFrame.Value> 
             <Visibility>Hidden</Visibility> 
            </DiscreteObjectKeyFrame.Value> 
           </DiscreteObjectKeyFrame> 
          </ObjectAnimationUsingKeyFrames> 
         </Storyboard> 
        </ControlTemplate.Resources> 
        <Border x:Name="border" BorderThickness="1" Padding="4" CornerRadius="3" 
        BorderBrush="Gray" Background="#FFA11616"> 
         <Grid> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="*" /> 
           <ColumnDefinition Width="Auto" /> 
          </Grid.ColumnDefinitions> 
          <ContentPresenter Grid.Column="0" VerticalAlignment="Center" Margin="0,0,3,0"/> 
          <Button x:Name="button" Grid.Column="1" Padding="2" FontSize="9" Content="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"/> 
         </Grid> 
        </Border> 
        <ControlTemplate.Triggers> 
         <EventTrigger RoutedEvent="UIElement.PreviewMouseLeftButtonUp" SourceName="button"> 
          <BeginStoryboard x:Name="OnClick1_BeginStoryboard" Storyboard="{StaticResource OnClick1}"/> 
         </EventTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Notez également que le EventTrigger est sur votre ControlTemplate et non sur le Button dans votre arborescence. Mais cela pourrait être juste la façon dont Blend génère le code.

Questions connexes