Domanda

Sto cercando di creare un controllo personalizzato in Silverlight che ridimensiona dinamicamente un elemento in ControlTemplate. Il primo tentativo di ControlTemplate è simile al seguente:

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

Tuttavia, questo thread del forum afferma che TemplateBinding funziona solo su derivati ??di FrameworkElements. ScaleTransform non è un FrameworkElement. C'è un lavoro in giro per questo? Qualche migliore pratica per questo tipo di situazione là fuori?

È stato utile?

Soluzione

Invece di associare le proprietà ScaleX e ScaleY di RenderTransform, puoi associare RenderTransform stesso. Il problema è che l'origine ha un doppio valore e hai bisogno di una trasformazione. Quindi devi essere in grado di convertire un doppio in una ScaleTransform. Puoi creare un IValueConverter per farlo:

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

Non puoi specificare un IValueConverter da usare in un TemplateBinding, quindi puoi usare un normale Binding con RelativeSource come TemplatedParent. In questo modo:

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

e devi posizionare IValueConverter nelle risorse della radice di ControlTemplate, nell'ambito del Binding:

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

Altri suggerimenti

Supponendo che si stiano sempre utilizzando elementi semplici come un rettangolo, è possibile associare l'altezza e la larghezza del rettangolo all'avanzamento, quindi utilizzare un convertitore di rilegatura per regolare il valore di conseguenza

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top