Bindings to ScaleX and ScaleY do not get updated
Posted: 25 Jan 2022, 12:18
I have a button control template and I want to animate the background scale without animating any contents of the button.
I have created two grids one inside the other, with the outer grid having the background and the inner grid being transparent. I use a storyboard to change scale of the outer grid and I want to use binding with a Converter to rescale the inner grid to the inverse of the outer grid. This works in WPF, but does not seem to work in Noesis.
The grids:
The converter:
The animation:
The convert function only gets called twice (once for scaleX, once for scaleY), but does not get called when the storyboard is played.
EDIT:
I tried to work around this by binding the whole ScaleTransform and using a converter to convert the Scale (instead of ScaleX and Y individually). It also doesn't work in Noesis.
What's interesting is that in WPF the Console.WriteLine gets called once at the beginning and then gets called multiple times when the storyboard plays (as expected). In Noesis however it gets called 3 times at the beginning (and doesn't get called during the storyboard). I suspect the triple call is related to me having three states in the VisualStateManager that work on the scale.
I have created two grids one inside the other, with the outer grid having the background and the inner grid being transparent. I use a storyboard to change scale of the outer grid and I want to use binding with a Converter to rescale the inner grid to the inverse of the outer grid. This works in WPF, but does not seem to work in Noesis.
The grids:
Code: Select all
<Grid x:Name="scalingGrid" Background="{TemplateBinding Background}" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="scalingGridScale" ScaleX="1.0" ScaleY="1.0"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Grid x:Name="reverseScalingGrid" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="{Binding ScaleX, ElementName=scalingGridScale, Converter={StaticResource multiplicativeInverseFloatConverter}, UpdateSourceTrigger=PropertyChanged}"
ScaleY="{Binding ScaleY, ElementName=scalingGridScale, Converter={StaticResource multiplicativeInverseFloatConverter}}"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>Code: Select all
public class MultiplicativeInverseFloatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
#if NOESIS
float var = (float)value;
#else
double var = (double)value;
#endif
System.Console.WriteLine(var.ToString());
return 1/var;
}Code: Select all
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="scalingGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="{StaticResource UCTransitionTime}" Value="1.33"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="scalingGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="{StaticResource UCTransitionTime}" Value="1.33"/>
</DoubleAnimationUsingKeyFrames>EDIT:
I tried to work around this by binding the whole ScaleTransform and using a converter to convert the Scale (instead of ScaleX and Y individually). It also doesn't work in Noesis.
Code: Select all
public class ReverseScaleTransformConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ScaleTransform trans = (ScaleTransform)value;
Console.WriteLine(trans.ScaleY.ToString());
#if NOESIS
return new ScaleTransform(1.0f / trans.ScaleX, 1.0f / trans.ScaleY);
#else
return new ScaleTransform(1.0 / trans.ScaleX, 1.0 / trans.ScaleY);
#endif
}Code: Select all
<Grid x:Name="scalingGrid" Background="{TemplateBinding Background}" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<ScaleTransform x:Name="scalingGridScale" ScaleX="1.0" ScaleY="1.0"/>
</Grid.RenderTransform>
<Grid x:Name="reverseScalingGrid" RenderTransformOrigin="0.5,0.5" RenderTransform="{Binding RenderTransform, ElementName=scalingGrid, Converter={StaticResource reverseScaleTransformConverter}, UpdateSourceTrigger=PropertyChanged}" >