我使用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代码如下
<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数据绑定吗?
发布于 2013-01-24 00:47:14
我假设您没有同时显示来自XAML的所有图像。
速度慢有两个可能的原因:
1-繁重的XAML解析和加载非常非常慢
2-绑定很棒,但都是顺序的,一个绑定会锁定其他绑定等等。
您可以尝试:
1-不要在设计时将不必要的控件添加到您的XAML中,在运行时添加它动态地创建控件,速度更快(或最快)。即使这些没有显示,也要这样做,记住问题出在解析和加载上。
2-如果可能的话,尝试使用异步绑定。通过这种方式,绑定不会相互锁定。
https://stackoverflow.com/questions/14483029
复制相似问题