【问题标题】:WPF-Performance issue when drag a view under other view将视图拖到其他视图下时出现 WPF 性能问题
【发布时间】:2020-10-14 06:41:59
【问题描述】:

在 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# wpf performance


    【解决方案1】:

    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>
    

    【讨论】:

    • @Maciek Świszczowski 非常感谢!它对我有用
    • 你问了一个准备充分的问题,在 Github 上有一个示例代码 - 令人惊讶的是你几天没有收到任何评论(我找到了你的问题,因为我按标签搜索你用过,所以标记得很好)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 2021-05-01
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多