2009-09-09 8 views
1

J'essaie de créer un contrôle personnalisé dans Silverlight qui met à l'échelle de manière dynamique un élément dans son ControlTemplate. Première tentative de ControlTemplate ressemble à ceci:Liaison à des transformations dans un ControlTemplate

<ControlTemplate TargetType="controls:ProgressBar"> 
    <Grid> 
     <Rectangle x:Name="TrackPart" Fill="{TemplateBinding Background}" HorizontalAlignment="Left" /> 
     <Rectangle x:Name="ProgressPart" Fill="Blue" > 
     <Rectangle.RenderTransform> 
     <ScaleTransform ScaleX="{TemplateBinding Progress}" /> 
      </Rectangle.RenderTransform> 
     </Rectangle> 
    </Grid> 
</ControlTemplate> 

Cependant, this forum thread affirme que TemplateBinding ne fonctionne que sur les dérivés de FrameworkElements. ScaleTransform n'est pas un FrameworkElement. Y a-t-il un travail pour ça? Toutes les meilleures pratiques pour ce genre de situation là-bas?

Répondre

6

Plutôt que de lier le ScaleX et ScaleY propriétés de RenderTransform, vous pouvez lier le RenderTransform lui-même. Le problème est que la source est une valeur double et que vous avez besoin d'une transformation. Vous devez donc être capable de convertir un double en ScaleTransform. Vous pouvez créer un IValueConverter à faire:

public class TransformConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is double) 
     { 
      double d = (double)value; 
      return new ScaleTransform { ScaleY = d, ScaleX = d }; 
     } 
     else 
     { 
      return new ScaleTransform(); 
     } 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Vous ne pouvez pas spécifier un IValueConverter à utiliser dans un TemplateBinding, de sorte que vous pouvez utiliser régulièrement avec liaison RelativeSource comme TemplatedParent. Comme ceci:

<Rectangle x:Name="ProgressPart" Fill="Blue" 
      RenderTransform="{Binding Path=Progress, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource converter1}}" > 

et vous devez placer le IValueConverter dans les ressources de la racine de ControlTemplate, portée de la liaison:

<ControlTemplate TargetType="controls:ProgressBar"> 
    <Grid> 
     <Grid.Resources> 
      <local:TransformConverter x:Key="converter1" /> 
     </Grid.Resources> 
+0

Merci beaucoup. Beaucoup mieux que ma solution de création se transforme dans la classe et lie à eux. –

1

En supposant que vous utilisez toujours des éléments simples comme un rectangle, vous pouvez lier la hauteur et la largeur du rectangle à l'état d'avancement, puis utiliser un convertisseur de liaison pour ajuster la valeur en conséquence

Questions connexes