首页 > 解决方案 > 将视图拖到其他视图下时出现 WPF 性能问题

问题描述

在 WPF 中将视图拖到另一个视图下时,如何解决性能问题?

目前,在使用 WPF 时,我遇到一个问题,当我将图像拖到标签的内容上时,它变得非常慢。我尝试增加标签的宽度和高度,然后将图像拖到标签的背景上(不包含内容),它仍然可以正常工作。但是每当图像被拖过Label的内容区域时,拖拽动作就会变得非常缓慢。对于我的测试项目的源代码,你可以在https://github.com/thanhbinh93-bn/wpf_drag_performance获得完整的源代码

这是我的测试项目:我有一个非常简单的窗口,其中包含一个 Imageview:

<Window x:Class="OverlapeTesting.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:OverlapeTesting"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid x:Name="container" Background="Red">
        <Image 
            Source="background.png" 
            Width="145" Height="90" 
            HorizontalAlignment="Left" 
            VerticalAlignment="Top"
            PreviewMouseLeftButtonDown="Image_PreviewMouseLeftButtonDown"
            PreviewMouseMove="Image_PreviewMouseMove"
            PreviewMouseUp="Image_PreviewMouseUp"
            x:Name="dragImage"/>
    </Grid>
</Window>

然后在后面的代码中,我将大约 10000 个标签添加到容器网格中。

public void AddLabels()
{
           
     for (int i = 0; i < 10000; i++)
     {
         Label lb = new Label();
         lb.Content = "WWW";
         lb.Foreground = Brushes.White;
         lb.FontSize = 20;
         container.Children.Add(lb);
         lb.Width = 300;
         lb.Height = 150;
         lb.Background = new SolidColorBrush(Colors.Green);
         //lb.Opacity = 0.1;
     }
}

可以通过更改其边距将图像拖动到容器网格中,如下所示:

private void Image_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
     m_pointPressToImage = e.GetPosition((sender as FrameworkElement).Parent as FrameworkElement);
     Mouse.Capture(dragImage);
}

private void Image_PreviewMouseMove(object sender, MouseEventArgs e)
{

   if (e.LeftButton == MouseButtonState.Pressed)
   {
       Point pCurrent = new Point();
       pCurrent = e.GetPosition((sender as FrameworkElement).Parent as FrameworkElement);

       double deltaX = (pCurrent.X - m_pointPressToImage.X);
       double deltaY = (pCurrent.Y - m_pointPressToImage.Y);

       Thickness margin = dragImage.Margin;
       margin.Left += deltaX;
       margin.Top += deltaY;

       dragImage.Margin = margin;
       m_pointPressToImage = pCurrent;
   }
}

private void Image_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    Mouse.Capture(null);
}

当我在空白区域拖动图像时,速度非常快。但是当我将图像拖到标签内容的区域(“WWW”)上时,它变得非常慢。

我该如何解决这个性能问题?提前致谢!

标签: c#wpfperformance

解决方案


BitmapCache会是你的朋友。

您只需将复杂的 UI 元素移动到单独的面板,然后将其缓存:

<Grid Background="Red">
    <Grid x:Name="container">
        <Grid.CacheMode>
            <BitmapCache />
        </Grid.CacheMode>
    </Grid>
    <Image 
        Source="background.png" 
        Width="145" Height="90" 
        HorizontalAlignment="Left" 
        VerticalAlignment="Top"
        PreviewMouseLeftButtonDown="Image_PreviewMouseLeftButtonDown"
        PreviewMouseMove="Image_PreviewMouseMove"
        PreviewMouseUp="Image_PreviewMouseUp"
        x:Name="dragImage"
        AllowDrop="False" />
</Grid>

推荐阅读