更改WP8上按钮边框的颜色时出现滞后

本文关键字:滞后 颜色 WP8 按钮 边框 更改 | 更新日期: 2023-09-27 17:57:51

我正在将一个对象移动到一堆按钮上,当这个对象位于按钮上时,我会更改边框的颜色。这没问题,我可以通过绑定、故事板或样式设置器/视觉状态来实现。当我在模拟器上运行它时,它运行得很好,很流畅,但当我在windows手机上运行它,当国家边界发生变化时,会有一个小的滞后。有办法避免这种情况吗?

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

额外

模拟器和实际设备之间的一个区别是触摸点的准确性。在模拟器中,您使用的鼠标具有更高的分辨率。在使用手指的设备上,精度要低得多,即毫米与像素。

我只是用一个简单的计数器和操纵_完成_事件中的一个断点来测试这一点。但这两种情况下的数字是相同的。它只试过运行一次故事板。

Extra2

为了澄清滞后,我看到:

我正在拖动一个平滑地跟随手指的元素,当我交叉到一个新的臀部时,我正在拖动的元素会停止一小段时间。按钮的颜色将发生更改,元素将再次移动。

当我在按钮改变颜色后向后移动时。当我在按钮之间移动时,该元素会随着我的手指平滑移动。

因此,当故事板被激活时会有一个滞后,可以看出我拖动的元素无法跟随手指。

因此,我正在努力寻找其他方法来改变手机上可能具有更好性能的颜色。因为它在模拟器上运行良好。

我测试了两种不同的亮度920和一种亮度520

2.代码示例

在Shawn Kendrot的帮助下使用Visual State Manager,来自另一个问题:为下面复制的颜色动画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>

请注意,它有一个鼠标悬停在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);
}

仍然存在滞后,其他人有可以测试的解决方案吗?

额外

由于问题可能是低fps,即当我想更改颜色时出现渲染问题,是否可以使用调度器?

因此,在我启动情节提要的第一个代码示例中,我可以调用视图中的一个函数来利用调度器?有人有这样做的想法吗?或者这是个好主意吗?

感谢所有的帮助,因为我不明白为什么我可以在屏幕上平滑地移动对象,但当我想更改边框的颜色时,我可以看到它滞后:/

更改WP8上按钮边框的颜色时出现滞后

我的应用程序中的动画存在性能问题,通常通过将移动元素的CacheMode属性设置为BitmapCache来解决这些问题。

其想法是,它指示框架对控件进行屏幕截图,并将生成的位图存储在GPU的内存中,这样控件就不必在每一帧上都重新绘制。

您可以看看这篇文章:CacheMode以及为什么它很重要,以获得更多的见解。

运行附加到调试器时,您得到的调试/性能信息是什么?

允许他们在应用程序构造函数的末尾添加以下内容:

        // Show graphics profiling information while debugging.
        if (Debugger.IsAttached)
        {
            // Display the current frame rate counters.
            Application.Current.Host.Settings.EnableFrameRateCounter = true;
            // Show the areas of the app that are being redrawn in each frame.
            //Application.Current.Host.Settings.EnableRedrawRegions = true;
            // Enable non-production analysis visualization mode,
            // which shows areas of a page that are handed off to GPU with a colored overlay.
            //Application.Current.Host.Settings.EnableCacheVisualization = true;
            // Prevent the screen from turning off while under the debugger by disabling
            // the application's idle detection.
            // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
            // and consume battery power when the user is not using the phone.
            PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
        }