Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#WPF ScrollViewer滚动将帧速率锁定为30fps,UI线程利用率非常低_C#_Wpf_Freeze_Frame Rate - Fatal编程技术网

C#WPF ScrollViewer滚动将帧速率锁定为30fps,UI线程利用率非常低

C#WPF ScrollViewer滚动将帧速率锁定为30fps,UI线程利用率非常低,c#,wpf,freeze,frame-rate,C#,Wpf,Freeze,Frame Rate,我很困惑,我看到UI线程几乎没有加载,时间线分析告诉我fps至少应该等于60,但真正的fps不稳定 因此,我有两个虚拟化StackPanel,它们都使用双动画来平滑滚动。(我知道)它们唯一不同的是,第一个是用xaml创建的,是一个ListView.ItemsPanelTemplate,由ListView的ItemSource属性管理;我在代码中手动创建的第二个面板,手动将其设置为手动创建的ScrollViewer对象的内容,并手动将每个子对象添加到此面板 创建代码: private void I

我很困惑,我看到UI线程几乎没有加载,时间线分析告诉我fps至少应该等于60,但真正的fps不稳定

因此,我有两个虚拟化StackPanel,它们都使用双动画来平滑滚动。(我知道)它们唯一不同的是,第一个是用xaml创建的,是一个ListView.ItemsPanelTemplate,由ListView的ItemSource属性管理;我在代码中手动创建的第二个面板,手动将其设置为手动创建的ScrollViewer对象的内容,并手动将每个子对象添加到此面板

创建代码:

private void InitializeItemsOwner()
{
    ItemsOwner = new VirtualizingStackPanel
    {
        Width = this.Width,
        Height = this.Height            
    };
    VirtualizingPanel.SetIsVirtualizing(ItemsOwner, true);
    VirtualizingPanel.SetCacheLengthUnit(ItemsOwner, VirtualizationCacheLengthUnit.Item);
    VirtualizingPanel.SetCacheLength(ItemsOwner, new VirtualizationCacheLength(2));
    VirtualizingPanel.SetVirtualizationMode(ItemsOwner, VirtualizationMode.Recycling);
    UpdateFrameworkElement(ItemsOwner, RenderSize, new Rect(RenderSize));
    PreviewMouseWheel += Managers.AnimationManager.ListView_PreviewMouseWheel;
}

private void InitializeScrollOwner()
{
    ScrollOwner = new ScrollViewer()
    {
        VerticalScrollBarVisibility = ScrollBarVisibility.Disabled,
        HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled
    };
    ScrollOwner.Content = ItemsOwner;
    ScrollOwner.InvalidateScrollInfo();
    UpdateFrameworkElement(ScrollOwner, RenderSize, new Rect(RenderSize));
    this.Content = ScrollOwner;
}

/// <summary>
/// Updates layout of FrameworkElement object
/// </summary>
/// <param name="element">Framework element to update</param>
/// <param name="availableSize">Meashre with availableSize</param>
/// <param name="finalRect">Arrange with finalRect</param>
private void UpdateFrameworkElement(FrameworkElement element, Size availableSize, Rect finalRect)
{
    element.Measure(availableSize);
    element.Arrange(finalRect);
    element.UpdateLayout();
}
所以对我来说非常有趣的一件事是,如果用某个矩形替换这个图像控件,任何其他简单的控件,30fps的锁定消失,在滚动动画期间,我有一个平滑的60fps。问题是在这个图像控件中,由于某些原因,这样的实例的安排很繁重,但是为什么探查器不告诉任何关于它的信息呢?我会错过一些重要的图像实例创建吗?如果是,我可以尝试解决这个问题吗? 谢谢你,如果你需要一些额外的细节,请让我知道。等待你的想法。

因此,问题在于阴影效应。第二个面板项的排列会导致其阴影效果被重新计算/重画或类似的内容。因此,解决方案是完全消除DropShadowEffect,或者您可以使用RenderTargetBitmap将具有阴影效果的整个控件渲染到BitmapSource对象,如所述。所以问题就结束了

private void AddChild(BitmapSource image)
{
    Image imageControl = new Image
    {
        Source = image,
        SnapsToDevicePixels = true,
        UseLayoutRounding = true
    };
    RenderOptions.SetBitmapScalingMode(imageControl, BitmapScalingMode.NearestNeighbor);
    imageControl.Effect = new System.Windows.Media.Effects.DropShadowEffect()
    {
        Color = Colors.Black
    };
    imageControl.CacheMode = new BitmapCache();
    Size imageSize = new Size(image.Width, image.Height);
    ItemsOwner.Children.Add(imageControl);

    UpdateFrameworkElement(imageControl, imageSize, new Rect(imageSize));
    ItemsOwner.UpdateLayout();
}