我正在将一个对象移到一堆按钮上,当这个对象移到一个按钮上时,我会更改边框的颜色。这没问题,我可以通过绑定(bind)、 Storyboard或样式 setter /视觉状态来做到这一点。当我在我的模拟器上运行它时它运行良好且流畅,但是当我在我的 Windows Phone 上运行它时,当国家边界发生变化时会有一点延迟。有没有办法避免这种情况?
<强>1。代码示例
<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>
和激活
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;
}
}
额外
模拟器和实际设备之间的一个区别是触摸点的准确性。在模拟器中,您使用具有更高分辨率的鼠标。在您使用手指的设备上,精度要低得多,即毫米与像素。
我刚刚用一个简单的计数器和 manipulation_completed_event 中的一个断点对此进行了测试。但是在这两种情况下计数是相同的。而且它只尝试运行 Storyboard一次。
Extra2
为了澄清我看到的延迟:
我正在拖动一个顺畅地跟随手指的元素,当我进入一个新按钮时,我正在拖动的元素会停止一会儿。按钮的颜色发生变化,元素再次移动。
当我在按钮改变颜色后返回时。当我在按钮之间移动时,元素会随着我的手指平稳地移动。
因此在 Storyboard被激活时存在延迟,并且可以看出我拖动的元素不能跟随手指。
因此,我正在尝试寻找替代方法来更改可能在手机上具有更好性能的颜色。因为它在模拟器上运行良好。
我在两台不同的 lumia 920s 和一台 lumia 520 上测试过
<强>2。代码示例
在 Shawn Kendrot 的帮助下使用 Visual State Manager,来自另一个问题:Using Dependency object for color animation WP8复制如下:
<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>
注意它有一个 MouseOver VisualState。然后分配样式并订阅事件处理程序
<Button Content="Drag over me" Style="{StaticResource ButtonStyle}" MouseEnter="OnButtonMouseEnter" MouseLeave="OnButtonMouseLeave"/>
并在事件处理程序中更改视觉状态。
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);
}
仍然有延迟,还有其他人有可以测试的解决方案吗?
额外
由于问题可能是低帧率,即当我想更改颜色时出现渲染问题,是否可以使用调度程序?
那么在我启动 Storyboard的第一个代码示例中,我可以改为调用 View 中的函数来利用调度程序吗?任何人都有这样做的想法,或者这是一个好主意吗?
感谢所有帮助,因为我不明白为什么我可以在屏幕上平滑地移动对象,但是当我想更改边框的颜色时,我会看到它滞后:/
最佳答案
我在我的应用程序中遇到过动画性能问题,并且通常通过将移动元素的 CacheMode
属性设置为 BitmapCache
来解决这些问题。
这个想法是它指示框架截取控件的屏幕截图并将生成的位图存储在 GPU 的内存中,这样就不必在每一帧都重新绘制控件。
可以看看这篇文章:CacheMode and why it matters了解更多信息。
关于c# - 在 WP8 上更改按钮边框颜色时滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23013961/