Pergunta

Eu estou tentando criar um controle personalizado no Silverlight que se adapta dinamicamente um elemento da mesma de ControlTemplate. Primeira tentativa do ControlTemplate é algo como isto:

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

No entanto, este tópico do fórum estados que TemplateBinding só funciona em derivados de FrameworkElements. ScaleTransform não é um FrameworkElement. Existe uma em torno do trabalho para isso? Quaisquer melhores práticas para este tipo de situação lá fora?

Foi útil?

Solução

Em vez de ligar as propriedades ScaleX e ScaleY do RenderTransform, você pode vincular o próprio RenderTransform. O problema é que a fonte é um valor duplo, e você precisa de uma transformação. Então, você precisa ser capaz de converter um duplo para um ScaleTransform. Você pode criar um IValueConverter fazer isso:

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

Você não pode especificar um IValueConverter para uso em uma TemplateBinding, assim você pode usar um regular ligação com RelativeSource como TemplatedParent. Como esta:

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

e você precisa colocar o IValueConverter nos recursos de raiz do ControlTemplate, no âmbito da Encadernação:

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

Outras dicas

Assumindo que você está sempre usando itens simples como um retângulo, você pode ligar a altura ea largura do retângulo para o progresso, e então usar um conversor de ligação para ajustar o valor em conformidade

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top