2008-11-29 12 views
8

Ho uno stile di controllo dei pulsanti e voglio cambiare il padding da qualunque versione legata ai dati debba essere regolata per un glifo che ha bisogno di un offset di 2 pixel. Userò SimpleButton da SimpleStyles.xaml come un esempio (... mostra dove il codice di attivazione è stato rimosso per concisione):Puoi fare "matematica" all'interno di Stili WPF legati ai dati

<Style x:Key="SimpleButton" TargetType="{x:Type Button}" BasedOn="{x:Null}"> 
    <Setter Property="FocusVisualStyle" Value="{DynamicResource SimpleButtonFocusVisual}"/> 
    <Setter Property="Background" Value="{DynamicResource NormalBrush}"/> 
    <Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}"/> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type Button}"> 
      <!-- We use Grid as a root because it is easy to add more elements to customize the button --> 
      <Grid x:Name="Grid"> 
      <Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"/> 

       <!-- Content Presenter is where the text content etc is placed by the control. The bindings are useful so that the control can be parameterized without editing the template --> 
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/> 
      </Grid> 
    ... 
    </Setter.Value>      
    </Setter> 
</Style> 

Quello che voglio fare è aggiungere un po 'margine extra dove Imbottitura = "{TemplateBinding Imbottitura}". Qualcosa come Padding = "{TemplateBinding Padding} + 2,0,0,0".

Esiste una sintassi XAML? In caso contrario, c'è un approccio migliore quando si fa questo in codice (Decoratore?)?

risposta

8

Attualmente XAML non analizza le espressioni nel legame della sintassi, ecc, tuttavia, è possibile utilizzare un IValueConverter o IMultiValueConverter per aiutare se stessi fuori:

XAML:

<Setter.Value> 
    <ControlTemplate TargetType="{x:Type Button}"> 
     <Grid x:Name="Grid"> 
     <Grid.Resources> 
      <local:ThicknessAdditionConverter x:Key="AdditiveThickness" /> 
     </Grid.Resources> 
     <Border x:Name="Border"> 
      <Border.Padding> 
       <Binding Path="Padding" RelativeSource="{RelativeSource TemplatedParent}" 
          Converter="{StaticResource AdditiveThickness}"> 
        <Binding.ConverterParameter> 
         <Thickness>2,0,0,0</Thickness> 
        </Binding.ConverterParameter> 
       </Binding> 
      </Border.Padding> 
     </Border> 
... 
</Setter.Value> 

codice IValueConverter dietro:

public class ThicknessAdditionConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) return new Thickness(0, 0, 0, 0); 
     if (!(value is Thickness)) throw new ArgumentException("Value not a thickness", "value"); 
     if (!(parameter is Thickness)) throw new ArgumentException("Parameter not a thickness", "parameter"); 

     var thickness = new Thickness(0, 0, 0, 0); 
     var t1 = (Thickness)value; 
     var t2 = (Thickness)parameter; 

     thickness.Left = t1.Left + t2.Left; 
     thickness.Top = t1.Top + t2.Top; 
     thickness.Right = t1.Right + t2.Right; 
     thickness.Bottom = t1.Bottom + t2.Bottom; 

     return thickness; 
    } 

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

No, non in questa versione di XAML: utilizzare un convertitore di valori per eseguire calcoli matematici.

+0

Si può fornire un esempio di usando un convertitore di valori per fare questa matematica - sembra più un cattivo uso per me. –

3

c'è un prodotto disponibile presso Blendables.com chiamato Eval Binding e semplice rilegatura fa questo ora. (Il prodotto non è gratuito) Controlla lo whitepaper qui

Ad esempio per il codice XAML a soffietto è necessario un convertitore per eseguire l'operazione.

<Ellipse Fill="Blue" Height="50" 
    Width="{Binding RelativeSource={RelativeSource Self}, 
     Path=Height, Converter={StaticResource MyConverter}}" /> 

Ma con EvalBinding si può fare come muggito

<Ellipse Fill="Blue" Height="50" 
    Width="{blendables:EvalBinding [{Self}.Height]/2}" /> 
1

È possibile eseguire alcuni semplici calcoli sfruttando le trasformazioni.

Partenza questo trucco che Charles Petzold si avvicinò con un molto tempo fa: http://www.charlespetzold.com/blog/2006/04/060223.html

Purtroppo, non sembra per aiutare il particolare scenario ... da quando si vuole solo modificare la proprietà di sinistra il tipo di spessore per il riempimento ... e che non è una proprietà di dipendenza che è possibile associare a solo.

Tuttavia, mi sono sentito in dovere di aggiungere questa risposta nel caso in cui aiuti gli altri che trovano la loro strada qui tramite Google o un altro motore di ricerca.

Problemi correlati