2008-11-29 8 views
8

Tengo un estilo de control de botones y deseo cambiar el relleno de lo que sea la versión enlazada a datos para ajustar para un glifo que necesita un desplazamiento de 2 píxeles. Voy a usar SimpleButton de SimpleStyles.xaml como un ejemplo (... muestra donde se extirpó el código de activación para la concisión):Puede hacer "matemática" dentro de WPF Estilos enlazados a datos

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

Lo que quiero hacer es añadir un poco de margen extra donde Relleno = "{TemplateBinding Relleno}". Algo así como Padding = "{TemplateBinding Padding} + 2,0,0,0".

¿Hay una sintaxis XAML para eso? Si no, ¿hay un mejor enfoque al hacer esto en el código (Decorador?)?

Respuesta

8

Actualmente XAML no analiza las expresiones en la unión de sintaxis, etc. Sin embargo, se puede usar un IValueConverter o IMultiValueConverter para ayudarse a cabo:

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> 

código IValueConverter atrás:

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, no en esta versión de XAML: use un convertidor de valor para hacer sus cálculos.

+0

¿Puede dar un ejemplo de usar un convertidor de valor para hacer estas operaciones matemáticas, me parece más un mal uso. –

3

hay un producto disponible en Blendables.com llamada Eval Encuadernación y simple unión hace esto ahora. (El producto no es gratuito) Consulte el whitepaper aquí

Por ejemplo, para el código XAML de abajo necesita un convertidor para realizar la operación.

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

Pero con EvalBinding usted puede hacer como abajo

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

Puede hacer algunas operaciones matemáticas simples aprovechando las transformaciones.

Control hacia fuera este truco que Charles Petzold ocurrió hace mucho tiempo: http://www.charlespetzold.com/blog/2006/04/060223.html

Por desgracia, no parece ayudar a su escenario particular ... ya que sólo desea cambiar la propiedad de la izquierda el tipo de grosor para el relleno ... y esa no es una propiedad de dependencia a la que pueda vincularse solo.

Sin embargo, me sentí obligado a agregar esta respuesta en el caso de que ayuda a otros que encuentran su camino aquí a través de Google u otro motor de búsqueda.

Cuestiones relacionadas