首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF MVVM treeview性能

WPF MVVM treeview性能
EN

Stack Overflow用户
提问于 2013-01-23 23:19:43
回答 1查看 1.3K关注 0票数 0

我使用MVVM模式来显示事务的树数据。

层次结构是Customer -> Accounts -> Transactions。

我有一个基类TreeItemViewModel,它实现了像IsExpanded,IsSelected等这样的基本依赖属性,它们是双向依赖属性。然后我有一堆类,比如CustomerViewModel,AccountViewModel,TransactionViewModel。其中每一个都有一个Children集合。因此,CustomerViewModel将包含一个AccountViewModels列表,每个列表都有自己的TransactionViewModels子代集合。然后我使用数据模板将XAML绑定到这些视图模型上,下面给出了一个示例(transactionviewmodel模板)。

当您展开一个节点时,将调用基类的IsExpanded方法,然后加载该节点的子节点-因此它是惰性加载。此外,当您展开一个客户节点时,它不仅加载帐户,还加载每个帐户的事务,因为它们需要一些统计数据。因此,当您展开account节点时,它所要做的就是根据数据模板绑定呈现transactionviewmodel,因为实际的子节点(transactionviewmodel对象)已经在该点加载了。

这种事务的渲染非常慢,特别是对于大容量的事务。

我已经测试了一个客户,一个账户有6000笔交易,并注释掉了大部分数据模板。时间安排如下

仅包含非图像列- 26s所有列,将图像转换器类更改为返回null而不是image - 51s包括图像的所有列: 20分钟

所以我担心的是

1)首先,加载6000个事务的27秒似乎非常慢,这是没有任何图像涉及的。是我的设计降低了它的速度吗?如果不重新设计整个系统,我如何才能做得更好?(目前不是一个选项)

2)如何加快图像处理速度,使应用程序不会挂起?

事务数据模板的Ok代码如下

代码语言:javascript
复制
                <Grid.RowDefinitions>
                    <RowDefinition Height="18" />
                </Grid.RowDefinitions>

                <TextBlock Text="{Binding TransactionId}" />
                <TextBlock Grid.Column="1" Text="{Binding CutOffDate}" />
                <Image Grid.Column="2" Source="{Binding AlarmImg, Converter={StaticResource stringToImageConverter}}" Height="25" HorizontalAlignment="Left"/>
                <TextBlock Grid.Column="3" Text="{Binding SourceSystemDesc}" />
                <Image Grid.Column="4" Margin="0,0,0,0" Source="{Binding CcmpImg, Converter={StaticResource stringToImageConverter}}" Height="25" ToolTip="CCMP Type" HorizontalAlignment="Left"/>
                <Image Grid.Column="5" Margin="0,0,0,0" Source="{Binding PrintedImg, Converter={StaticResource stringToImageConverter}}" Height="25" ToolTip="Printed" HorizontalAlignment="Left"/>
                <Image Grid.Column="6" Margin="0,0,0,0" Source="{Binding AppRejImg, Converter={StaticResource stringToImageConverter}}" Height="25" ToolTip="Approved/Rejected" HorizontalAlignment="Left"/>
                <Image Grid.Column="7" Margin="0,0,0,0" Source="{Binding LockImg, Converter={StaticResource stringToImageConverter}}" Height="25" ToolTip="Locked" HorizontalAlignment="Left"/>
                <TextBlock Grid.Column="8" Style="{StaticResource myTxnStyleColor}" Text="{Binding TxnAmount}" HorizontalAlignment="Right"/>
                <TextBlock Grid.Column="9" Text="{Binding TxnCurrency}" HorizontalAlignment="Right" />
                <Image Grid.Column="10" Margin="0,0,0,0" Source="{Binding CurrencyImg, Converter={StaticResource stringToImageConverter}}" Height="25"/>
            </Grid>
        </DataTemplate>

最后,静态资源转换器返回一个空白图像

代码语言:javascript
复制
    using System;
using System.Globalization;
using System.Runtime.Caching;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Citi.Rbcs.UI.Windows.HelperClasses
{
    public class StringToImageConverter : IValueConverter
    {
        private static readonly BitmapImage BlankImage =
            new BitmapImage(new Uri("pack://application:,,,/Resources/Images/Blank.gif"));

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                return BlankImage;

                var imageUrl = value as string;
                if (string.IsNullOrEmpty(imageUrl)) return BlankImage;

                // Strip out the Image name so we ignore path
                if (imageUrl.LastIndexOf(@"\") != -1)
                    imageUrl = imageUrl.Substring(imageUrl.LastIndexOf(@"\") + 1);
                if (imageUrl.LastIndexOf(@"/") != -1)
                    imageUrl = imageUrl.Substring(imageUrl.LastIndexOf(@"/") + 1);

                var image = MemoryCache.Default.Get(imageUrl) as ImageSource;

                if (image == null)
                {
                    image = new BitmapImage(new Uri("pack://application:,,,/Resources/Images/" + imageUrl));
                    MemoryCache.Default.Set(imageUrl, image, new CacheItemPolicy());
                }

                return image;
            }
            catch (Exception)
            {
                return BlankImage;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

任何帮助都将非常感谢,理想情况下,我希望使用此层次结构数据的WPF树视图,您可以在大约5-10秒内展开一个包含6000个子节点的节点。是什么让它花了这么长时间,仅仅是MVVM数据绑定吗?

EN

回答 1

Stack Overflow用户

发布于 2013-01-24 00:47:14

我假设您没有同时显示来自XAML的所有图像。

速度慢有两个可能的原因:

1-繁重的XAML解析和加载非常非常慢

2-绑定很棒,但都是顺序的,一个绑定会锁定其他绑定等等。

您可以尝试:

1-不要在设计时将不必要的控件添加到您的XAML中,在运行时添加它动态地创建控件,速度更快(或最快)。即使这些没有显示,也要这样做,记住问题出在解析和加载上。

2-如果可能的话,尝试使用异步绑定。通过这种方式,绑定不会相互锁定。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14483029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档