Question

J'essaie de créer un contrôle personnalisé dans Silverlight qui redimensionne de manière dynamique un élément de son ControlTemplate. La première tentative du ControlTemplate ressemble à ceci:

<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>

Toutefois, cela Le fil du forum indique que TemplateBinding ne fonctionne que sur les dérivés de FrameworkElements. ScaleTransform n'est pas un FrameworkElement. Y a-t-il un moyen de contourner ce problème? Des bonnes pratiques pour ce genre de situation?

Était-ce utile?

La solution

Plutôt que de lier les propriétés ScaleX et ScaleY de RenderTransform, vous pouvez lier 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 pouvoir convertir un double en ScaleTransform. Vous pouvez créer un IValueConverter pour le 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, vous pouvez donc utiliser un Binding classique avec RelativeSource en tant que TemplatedParent. Comme ceci:

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

et vous devez placer IValueConverter dans les ressources de la racine de ControlTemplate, dans le cadre de Binding:

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

Autres conseils

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top