I'm moving a object over a bunch of Buttons, and when this object is over a button I change the color of the border. This is no problem, I can do this through bindings, storyboards or style setters/Visual state. When I run this on my emulator it works nice and smooth, but when I run it on my windows phone, there is a small lag when the Border of the country changes. Is there a way to avoid this?
1. CODE Example
<Button x:Name="Button1" BorderThickness="0" BorderBrush="Transparent">
<Button.Template>
<ControlTemplate x:Name="Control">
<Path x:Name="CountryUser" Style="{StaticResource style_ColorButton}" Data="{Binding UserView.buttonData}" Fill="{StaticResource ButtonBackground}">
<Path.Resources>
<Storyboard x:Name="StoryBoard1">
<ColorAnimation Storyboard.TargetName="User" Storyboard.TargetProperty="(Stroke).(SolidColorBrush.Color)" To="Blue" Duration="0"/>
</Storyboard>
</Path.Resources>
</Path>
</ControlTemplate>
</Button.Template>
and activation
foreach (UIElement x in ElementsAtPoint)
{
f = x as FrameworkElement;
if (f is Path)
{
try
{
h = f as Path;
Storyboard sb = h.Resources["StoryBoard1"] as Storyboard;
sb.Begin();
}
catch
{
}
break;
}
}
Extra
One difference which comes to mind between emulator and an actual device is the accuracy of the touch point. In the emulator you use a mouse which has much higher resolution. On a device where you're using your finger the accuracy is much lower, i.e. millimeters vs pixels.
I just tested this with a simple counter and a break point in the manipulation_completed_event. But the count is the same in both cases. And it only tried to run the storyboard once.
Extra2
To clarify the lag I see:
I am dragging an element that follows the finger smoothly, when I cross into a new buttton, the element I am dragging stops a short while. The color of the button is changed and the element moves again.
When I move back after the button has changed the color. The element moves smoothly with my finger when I move between the buttons.
Therefore there is a lag when the storyboard is activated and it is seen in that the element I drag cannot follow the finger.
I am therefore trying to find alternativ ways to change the color that might have better performance, on the Phone. Beacuse it works fine on the emulator.
I have tested on two different lumia 920s and one lumia 520
2. Code Example
Using Visual State Manager with help from Shawn Kendrot, from another question: Using Dependency object for color animation WP8 replicated below:
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
<Setter Property="Padding" Value="10,5,10,6"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="White"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Orange"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneButtonBasePressedForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Notice it has a MouseOver VisualState. Then assign the style and subscribe to the event handlers
<Button Content="Drag over me" Style="{StaticResource ButtonStyle}" MouseEnter="OnButtonMouseEnter" MouseLeave="OnButtonMouseLeave"/>
And in the event handler change the visual state.
private void OnButtonMouseEnter(object sender, MouseEventArgs e)
{
VisualStateManager.GoToState((Control)sender, "MouseOver", true);
}
private void OnButtonMouseLeave(object sender, MouseEventArgs e)
{
VisualStateManager.GoToState((Control)sender, "Normal", true);
}
Still with lag, Anyone else have a solution that could be tested?
Extra
Since the issue might be low fps, i.e. a render problem when I want to change the color, could the dispatcher be used ?
So in the first code example where I start a storyboard, I could instead call a function in the view to utilize the dispatcher? Anyone has an idea for doing this and or if it is a good idea?
appreciating all the help, since I cannot understand why I can move objects smooth around on the screen but when I want to change the color of the border I can see it lagging :/