none
WPF性能问题 RRS feed

  • 问题

  • 最近用WPF做项目,但是一直有个问题深深的困扰着我,那就是WPF的性能问题,而且搜索了很多建议和解决方案都不能有效的解决。
    问题如下:

    我在主界面上放置了一个uniformgrid,固定6列,行数根据内容的条数动态确定,由于数据量比较大所以外层嵌套了scrollviewer也设置了相关属性,也尝试过在uniformgrid的cachemode中用bitmapchche,效果不明显,在uniformgrid中的每个child都是我自己定义的usercontrol,首次加载的时候很慢我还可以理解可能是加载内容过多(可能大概有200个左右usercontrol),当加载完成之后,当我一旦拖动滚动条,整个机器就卡死了,必须重启才能解决。(机器配置还是可以的2G内存,Core3.06GHZ双核处理器)。后来我又试过通过分页的方式解决,每页显示20个usercontrol,速度好了很多,但有时候当我翻页的时候又会出现卡顿的情况,而且还比较严重。求大神给点提示吧,谢谢了


    2012年10月17日 1:53

答案

  • 产品图片大小? 把图片绑定去除后,效率依然很低么?

    Wanpeng wanpeng.ones@gmail.com


    问题解决了,就是图片绑定的问题,我绑定的图片路径是string类型的,所以界面会进行转化,因此会卡,我在绑定上加了转换器Converter之后,然后把IsAsync = true,效率马上提上来了,还是谢谢回复
    • 已标记为答案 potato Yan 2012年10月18日 8:48
    2012年10月18日 8:48

全部回复

  • 有人知道么,求回复啊
    2012年10月17日 2:46
  • 你的UserControl是如何设计的?

    Wanpeng wanpeng.ones@gmail.com

    2012年10月17日 2:50
  • usercontrol里面包含一些产品信息:产品图片,产品名称,以及产品的状态
    2012年10月17日 3:37
  • 你的UserControl是如何设计的?

    Wanpeng wanpeng.ones@gmail.com

    usercontrol里面包含一些产品信息:产品图片,产品名称,以及产品的状态
    2012年10月17日 3:37
  • 没人看么....
    2012年10月17日 5:14
  • 首先, 在显示个数比较多的情况下, 需要作虚拟化处理:

    可以做控件的虚拟化和数据的虚拟化, 控件的虚拟化选择实现了虚拟化的容器即可,数据的虚拟化需要你自己处理.

    其次,20个item分页会卡顿, 感觉你的usercontrol或者是得到数据的过程有耗时的操作阻塞UI线程.

    你需要检查下你的usercontrol和数据源 .

    代码没有问题的话,200左右的item不会出现这种情况.

    我做过5000左右的item,所有item带图片和文字, 只做控件虚拟化内存都不会超过200M.

    如果可以, 可以共享你的代码让大家来帮你分析下原因.


    Thanks! Damon.Tian

    2012年10月17日 11:33
  • 首先, 在显示个数比较多的情况下, 需要作虚拟化处理:

    可以做控件的虚拟化和数据的虚拟化, 控件的虚拟化选择实现了虚拟化的容器即可,数据的虚拟化需要你自己处理.

    其次,20个item分页会卡顿, 感觉你的usercontrol或者是得到数据的过程有耗时的操作阻塞UI线程.

    你需要检查下你的usercontrol和数据源 .

    代码没有问题的话,200左右的item不会出现这种情况.

    我做过5000左右的item,所有item带图片和文字, 只做控件虚拟化内存都不会超过200M.

    如果可以, 可以共享你的代码让大家来帮你分析下原因.


    Thanks! Damon.Tian


    谢谢你的回复,控件的虚拟化我用了bitmapcache,数据的虚拟化不是很懂。代码的话很多,不知道该如何上传,方便加QQ指教一下么,710148546?
    我大体阐述一下数据的获取过程,主界面载入的时候通过代码逻辑我获得了一个包含所有产品信息的usercontrol的list,将这个list进行分页,每页显示20个,翻页也是操作的这个list,我调试过代码获取list的过程并不是很耗时间,时间主要在usercontrol的加载上
    2012年10月18日 1:12
  • 我贴一下我的usercontrol的代码吧,是不是这个有问题

    XAML:

    <UserControl x:Class="TaianSUCCEED.MineMonitoringSystem.WPF.UserInterface.MonitorState"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:GridHelperLibrary;assembly=GridHelper"
                 mc:Ignorable="d" 
                 Height="150" Width="200" MouseEnter="UserControl_MouseEnter" MouseLeave="UserControl_MouseLeave">
        <Border BorderThickness="1" CornerRadius="10" BorderBrush="Black">
            <Grid Name="_MainGrid">
                <Grid.RowDefinitions>
                    <RowDefinition Height="30"/>
                    <RowDefinition  Height="30"/>
                    <RowDefinition  Height="30"/>
                    <RowDefinition Height="60"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition Width="60"/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Label Content="{Binding 安装位置}" HorizontalAlignment="Center" Grid.Row="2" Grid.ColumnSpan="3"/>
                <Border Grid.RowSpan="2" BorderThickness="0,0,1,1" CornerRadius="3" BorderBrush="Black">
                    <Image Source="{Binding imagePath}" RenderOptions.BitmapScalingMode="LowQuality"/>
                </Border>
                <Label Content="设备编号:" Grid.Column="1" />
                <Label Content="{Binding 设备编号}" Grid.Column="2"/>
                <Label Content="通道数目:" Grid.Column="1" Grid.Row="1"/>
                <Label Content="{Binding 通道数目}" Grid.Column="2" Grid.Row="1"/>
                <Grid Grid.Row="3" Grid.ColumnSpan="3" Name="_MonitorStateGrid">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="30"/>
                        <RowDefinition Height="30"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="60"/>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Label Content="连接位置:"/>
                    <Label Content="状态:" Grid.Column="0" Grid.Row="1"/>
                </Grid>
            </Grid>
        </Border>
       
    </UserControl>
    

    后台代码:

    public partial class MonitorState : UserControl
        {
            public MonitorState(SensorDataEntity entity)
            {
                InitializeComponent();
                this.DataContext = entity;
                this.Name = "编号" +entity.PositionID.ToString();
                ReLoaded();
            }
            /// <summary>
            /// 重新加载数据和状态
            /// </summary>
            public void ReLoaded()
            {
                SensorDataEntity entity = this.DataContext as SensorDataEntity;
                StackPanel panel = new StackPanel();
                panel.Orientation = Orientation.Horizontal;
                panel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                StackPanel toolTipPanel = new StackPanel();
                toolTipPanel.Background = new SolidColorBrush(Colors.LightBlue);
                if (entity != null)
                {
                    Label labelTitle = new Label();
                    labelTitle.Content = "传输数据";
                    toolTipPanel.Children.Add(labelTitle);
                    if (entity.通道1 != null)
                    {
                        Label labelChannel = new Label();
                        labelChannel.Content = entity.通道1.连接位置;
                        Ellipse channel1State = new Ellipse();
                        channel1State.Width = 10;
                        channel1State.Height = 10;
                        if (entity.通道1.warningColor != null)
                        {
                            channel1State.Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString(entity.通道1.warningColor));
                        }
                        else
                        {
                            channel1State.Fill = new SolidColorBrush(Colors.Gray);
                        }
                        _MonitorStateGrid.Children.Add(labelChannel);
                        _MonitorStateGrid.Children.Add(channel1State);
                        labelChannel.SetValue(Grid.ColumnProperty, 1);
                        channel1State.SetValue(Grid.ColumnProperty, 1);
                        channel1State.SetValue(Grid.RowProperty, 1);
                        Label label = new Label();
                        label.Content = entity.通道1.连接位置 + ":" + entity.通道1.传输数据;
                        toolTipPanel.Children.Add(label);
                    }
                    if (entity.通道2 != null)
                    {
                        Label labelChannel = new Label();
                        labelChannel.Content = entity.通道2.连接位置;
                        Ellipse channel2State = new Ellipse();
                        channel2State.Width = 10;
                        channel2State.Height = 10;
                        if (entity.通道2.warningColor != null)
                        {
                            channel2State.Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString(entity.通道2.warningColor));
                        }
                        else
                        {
                            channel2State.Fill = new SolidColorBrush(Colors.Gray);
                        }
                        _MonitorStateGrid.Children.Add(labelChannel);
                        _MonitorStateGrid.Children.Add(channel2State);
                        labelChannel.SetValue(Grid.ColumnProperty, 2);
                        channel2State.SetValue(Grid.ColumnProperty, 2);
                        channel2State.SetValue(Grid.RowProperty, 1);
    
                        Label label = new Label();
                        label.Content = entity.通道2.连接位置 + ":" + entity.通道2.传输数据;
                        toolTipPanel.Children.Add(label);
                    }
                    if (entity.通道3 != null)
                    {
                        Label labelChannel = new Label();
                        labelChannel.Content = entity.通道3.连接位置;
                        Ellipse channel3State = new Ellipse();
                        channel3State.Width = 10;
                        channel3State.Height = 10;
                        if (entity.通道3.warningColor != null)
                        {
                            channel3State.Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString(entity.通道3.warningColor));
    
                        }
                        else
                        {
                            channel3State.Fill = new SolidColorBrush(Colors.Gray);
                        }
                        _MonitorStateGrid.Children.Add(labelChannel);
                        _MonitorStateGrid.Children.Add(channel3State);
                        labelChannel.SetValue(Grid.ColumnProperty, 3);
                        channel3State.SetValue(Grid.ColumnProperty, 3);
                        channel3State.SetValue(Grid.RowProperty, 1);
                        Label label = new Label();
                        label.Content = entity.通道3.连接位置 + ":" + entity.通道3.传输数据;
                        toolTipPanel.Children.Add(label);
                    }
                    if (entity.通道4 != null)
                    {
                        Label labelChannel = new Label();
                        labelChannel.Content = entity.通道4.连接位置;
                        Ellipse channel4State = new Ellipse();
                        channel4State.Width = 10;
                        channel4State.Height = 10;
                        if (entity.通道4.warningColor != null)
                        {
                            channel4State.Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString(entity.通道4.warningColor));
    
                        }
                        else
                        {
                            channel4State.Fill = new SolidColorBrush(Colors.Gray);
                        }
                        _MonitorStateGrid.Children.Add(labelChannel);
                        _MonitorStateGrid.Children.Add(channel4State);
                        labelChannel.SetValue(Grid.ColumnProperty, 4);
                        channel4State.SetValue(Grid.ColumnProperty, 4);
                        channel4State.SetValue(Grid.RowProperty, 1);
                        Label label = new Label();
                        label.Content = entity.通道4.连接位置 + "四:" + entity.通道4.传输数据;
                        toolTipPanel.Children.Add(label);
                    }
                    _MainGrid.Children.Add(panel);
                    panel.SetValue(Grid.RowProperty, 2);
                    this.ToolTip = toolTipPanel;
                }
                
            }
            private void UserControl_MouseEnter(object sender, MouseEventArgs e)
            {
                this.Background = new SolidColorBrush(Colors.AntiqueWhite);
            }
    
            private void UserControl_MouseLeave(object sender, MouseEventArgs e)
            {
                this.Background = null;
            }
            
        }

    2012年10月18日 1:19
  • 求高人指教啊
    2012年10月18日 2:15
  • 产品图片大小? 把图片绑定去除后,效率依然很低么?

    Wanpeng wanpeng.ones@gmail.com


    • 已编辑 Wanpeng 2012年10月18日 6:14
    2012年10月18日 6:13
  • 产品图片大小? 把图片绑定去除后,效率依然很低么?

    Wanpeng wanpeng.ones@gmail.com


    问题解决了,就是图片绑定的问题,我绑定的图片路径是string类型的,所以界面会进行转化,因此会卡,我在绑定上加了转换器Converter之后,然后把IsAsync = true,效率马上提上来了,还是谢谢回复
    • 已标记为答案 potato Yan 2012年10月18日 8:48
    2012年10月18日 8:48