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