template style para modern for data wpf data-binding templates styles

style - ¿Puedes hacer "cálculos matemáticos" dentro de los estilos de WPF vinculados a datos?



wpf templates (6)

Tengo un estilo de control de botón y quiero cambiar el relleno de lo que sea la versión de datos vinculados para ajustar para un glifo que necesita un desplazamiento de 2 píxeles. Usaré SimpleButton de SimpleStyles.xaml como un ejemplo (... muestra dónde se eliminó el código de activación por concisión):

<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 agregar un margen extra donde Padding = "{TemplateBinding Padding}". 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?)?


Hay un producto disponible en Blendables.com llamado Eval Binding y Simple Binding hace esto ahora. (El producto no es gratis) Eche un vistazo al documento técnico aquí

Por ejemplo, para el siguiente código XAML 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 puede hacer como abajo

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


No, no en esta versión de XAML: use un convertidor de valor para hacer sus cálculos.


Actualmente XAML no analiza expresiones en sintaxis de enlace, etc. Sin embargo, puede usar un IValueConverter o IMultiValueConverter para ayudarse a sí mismo:

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 de IValueConverter detrá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(); } }


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

Mira este truco que Charles Petzold ideó hace mucho tiempo: http://www.charlespetzold.com/blog/2006/04/060223.html

Desafortunadamente, no parece ayudar a su escenario particular ... ya que solo quiere cambiar la propiedad Izquierda del tipo 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 ayude a otros que encuentran su camino aquí a través de Google u otro motor de búsqueda.