Pregunta

Estoy tratando de crear un control personalizado en Silverlight que escala dinámicamente un elemento en su ControlTemplate. El primer intento de la plantilla ControlTemplate se ve así:

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

Sin embargo, this el hilo del foro indica que TemplateBinding solo funciona en derivados de FrameworkElements. ScaleTransform no es un FrameworkElement. ¿Hay una solución para esto? ¿Alguna de las mejores prácticas para este tipo de situación?

¿Fue útil?

Solución

En lugar de enlazar las propiedades ScaleX y ScaleY de RenderTransform, puede enlazar el RenderTransform mismo. El problema es que la fuente es un valor doble y usted necesita una Transformación. Así que necesitas poder convertir un doble a un ScaleTransform. Puedes crear un IValueConverter para hacer eso:

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();
    }
}

No puede especificar un IValueConverter para usar en un TemplateBinding, así que puede usar un enlace regular con RelativeSource como TemplatedParent. Así:

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

y necesita colocar el IValueConverter en los recursos de la raíz de ControlTemplate, en el ámbito del Enlace:

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

Otros consejos

Suponiendo que siempre usa elementos simples como un rectángulo, puede vincular la altura y el ancho del rectángulo al progreso, y luego usar un convertidor de encuadernación para ajustar el valor en consecuencia

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top