0

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

层次结构是客户 -> 帐户 -> 交易。

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

当你扩展一个节点时,基类的 IsExpanded 方法被调用,然后加载节点的子节点——所以它是延迟加载。此外,当您展开客户节点时,它不仅会加载账户,还会加载每个账户的交易,因为它们是一些统计数据所需要的。因此,当您展开帐户节点时,它所要做的就是根据数据模板绑定呈现事务视图模型,因为此时已经加载了实际的子节点(事务视图模型对象)。

它的这种交易呈现非常缓慢,尤其是对于大量交易。

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

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

所以我的担忧是

1)首先,加载 6000 笔交易的 27 秒似乎很慢,而且不涉及任何图像。是我的设计减慢了它的速度吗?如果不重新设计整个东西,我怎么能做得更好?(此时不是一个选项)

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

下面的交易数据模板的好的代码


                <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>

最后静态资源转换器触发返回空白图像

    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 数据绑定吗?

4

1 回答 1

0

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

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

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

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

你可以试试:

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

2 - 如果可能,尝试使用异步绑定。这样,绑定不会相互锁定。

于 2013-01-23T16:47:13.683 回答