2010-06-19 6 views
1

Je suis nouveau à WPF, et je voudrais savoir comment réutiliser un xaml ennuyeux je dois éviter la duplication.WPF style/modèle de contrôle réutilisation

<Button Cursor="Hand" HorizontalAlignment="Left" Margin="0,0,0,0" x:Name="MyButton" Style="{StaticResource ButtonTemplate}" Width="286" Content="hi!" Focusable="False" IsTabStop="False"/> 
<Button Cursor="Hand" HorizontalAlignment="Left" Margin="0,0,0,0" x:Name="MyButton2" Style="{StaticResource ButtonTemplate}" Width="286" Content="hi 2!" Focusable="False" IsTabStop="False"/> 

Je voudrais vraiment utiliser quelque chose comme ce modèle:

<Style TargetType="{x:Type Button}" x:Key="ButtonTemplate"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type Button}"> 
         <Grid x:Name="btGrid"> 
          <Path Cursor="Hand" HorizontalAlignment="Left" Stretch="Fill" Stroke="{x:Null}" Opacity="0" x:Name="path"/> 
          <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True" Visibility="Hidden" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top"/> 
         </Grid> 
         <ControlTemplate.Triggers> 
          <EventTrigger RoutedEvent="Button.PreviewMouseLeftButtonDown"> 
           <EventTrigger.Actions> 
            <BeginStoryboard> 
             <Storyboard SlipBehavior="Slip" BeginTime="00:00:00"> 
              <MediaTimeline Source="{Binding StringFormat={}, Path=Name}" Storyboard.TargetName="{Binding StringFormat={}_wma, Path=Name}"/> 
                <ObjectAnimationUsingKeyFrames Storyboard.TargetName="{Binding StringFormat=key{}, Path=Name}" Storyboard.TargetProperty="Visibility"> 
      <DiscreteObjectKeyFrame KeyTime="0"> 
       <DiscreteObjectKeyFrame.Value> 
        <Visibility> 
         Visible 
        </Visibility> 
       </DiscreteObjectKeyFrame.Value> 
      </DiscreteObjectKeyFrame> 
     </ObjectAnimationUsingKeyFrames> 
             </Storyboard> 
            </BeginStoryboard> 
           </EventTrigger.Actions> 
          </EventTrigger> 
          <EventTrigger RoutedEvent="Button.PreviewMouseLeftButtonUp"> 
           <EventTrigger.Actions> 
            <BeginStoryboard> 
             <Storyboard> 
              <ObjectAnimationUsingKeyFrames Storyboard.TargetName="{Binding StringFormat=key{}, Path=Name}" Storyboard.TargetProperty="Visibility"> 
      <DiscreteObjectKeyFrame KeyTime="0"> 
       <DiscreteObjectKeyFrame.Value> 
        <Visibility> 
         Hidden 
        </Visibility> 
       </DiscreteObjectKeyFrame.Value> 
      </DiscreteObjectKeyFrame> 
     </ObjectAnimationUsingKeyFrames> 
             </Storyboard> 
            </BeginStoryboard> 
           </EventTrigger.Actions> 
          </EventTrigger> 
          <Trigger Property="IsFocused" Value="True"/> 
          <Trigger Property="IsDefaulted" Value="True"/> 
          <Trigger Property="IsMouseOver" Value="True"/> 
          <Trigger Property="IsPressed" Value="True"/> 
          <Trigger Property="IsEnabled" Value="False"/> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

Et je voudrais que le {Binding StringFormat = {}, Path = Nom} pour pointer le nom du bouton, par exemple "MyButton", "MyButton2", etc.

Lorsque j'exécute ce code, j'obtiens l'erreur "Impossible de geler l'arborescence de la chronologie de Storyboard pour une utilisation sur plusieurs threads". :/Je comprends c'est parce que j'utilise la liaison dans un storyboard, correct? Je ne sais pas quoi faire pour que ça marche.

En outre, je voudrais aussi faire de ToggleVisibility de l'image un template, qui accepte une fois les valeurs "Visible" et "Hidden". Merci d'avance!

Répondre

1

Vous pouvez toujours définir des propriétés autres que Modèle dans votre style.

<Style TargetType="{x:Type Button}" 
      x:Key="ButtonTemplate"> 
     <Setter Property="Cursor" Value="Hand" /> 
     <Setter Property="HorizontalAlignment" Value="Left" /> 
     <Setter Property="Margin" Value="0,0,0,0" /> 
     <Setter Property="Width" Value="286" /> 
     <Setter Property="Focusable" Value="False" /> 
     <Setter Property="IsTabStop" Value="False" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Button}"> 
        ... 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Ce qui rend votre code ressemblent

<Button x:Name="MyButton" Style="{StaticResource ButtonTemplate}" Content="hi!" /> 
    <Button x:Name="MyButton2" Style="{StaticResource ButtonTemplate}" Content="hi 2!" /> 
+0

Salut, merci pour votre réponse, mais cela ne fonctionne pas ... Je reçois toujours le même { « ne peut pas geler cet arbre de calendrier Storyboard pour une utilisation sur les threads. »} Exception. – Rita

+0

Ok, Que voulez-vous dire par cette ligne: decyclone

0

Ouais créer un style avec le type de cible comme bouton ferait l'affaire.

Tip: Il est toujours recommandé d'écrire toutes les informations de style telles que bordure, arrière-plan, modèles, etc., sous la section ressource de votre code et de les appliquer aux contrôles. Ça va donner une bonne lisibilité.

HTH :)