0

トランザクションのツリー データを表示するために MVVM パターンを使用しています。

階層は、顧客 -> アカウント -> トランザクションです。

IsExpanded、IsSelected など、双方向の依存関係プロパティである基本的な依存関係プロパティを実装する基本クラス TreeItemViewModel があります。それから、CustomerViewModel、AccountViewModel、TransactionViewModel などのクラスがたくさんあります。それぞれに Children コレクションがあります。そのため、CustomerViewModel には AccountViewModels のリストが含まれ、それぞれが TransactionViewModels の独自の Children コレクションを持っています。次に、datatemplates を使用して XAML をこれらのビュー モデルにバインドしています。1 つの例 (transactionviewmodel テンプレート) を以下に示します。

ノードを展開すると、基本クラスの IsExpanded メソッドが呼び出され、ノードの子がロードされるため、遅延ロードになります。さらに、Customer ノードを展開すると、アカウントだけでなく、いくつかの統計データに必要な各アカウントのトランザクションも読み込まれます。したがって、アカウント ノードを展開すると、実際の子 (transactionviewmodel オブジェクト) がその時点で既に読み込まれているため、datatemplate バインディングに従って transactionviewmodels をレンダリングするだけで済みます。

特に大量の場合、このトランザクションのレンダリングは非常に遅くなります。

私は 1 人の顧客、1 つのアカウントで 6000 のトランザクションを持ち、ほとんどのデータ テンプレートをコメントアウトしてテストしました。タイミングは以下の通り

画像以外の列のみが含まれる - 26 秒 すべての列、画像の代わりに null を返すように画像コンバーター クラスを変更 - 51 秒 画像を含むすべての列: 20 分

だから私の懸念は

1) まず、27 秒で 6000 トランザクションをロードすると非常に遅く見えますが、これには画像が含まれていません。速度を落としているのは私の設計でしょうか?全体を再設計せずに、どうすればより良くできるのでしょうか? (現時点ではオプションではありません)

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データバインディングだけですか?

4

1 に答える 1

0

XAML のすべての画像を同時に表示しているとは限りません。

遅くなる原因として、次の 2 つが考えられます。

1 - 負荷の高い XAML の解析と読み込みが非常に遅い

2 - バインディングは優れていますが、シーケンシャルであり、バインディングは他のバインディングをロックします。

あなたが試すことができます:

1 - 設計時に必要なコントロールを XAML に追加しないでください。実行時に追加すると、動的にコントロールを作成する方が高速 (または最速) になります。これらが表示されていなくても、問題は解析と読み込みにあることに注意してください。

2 - 可能であれば、非同期バインディングを使用してみてください。このように、バインディングは互いにロックしません。

于 2013-01-23T16:47:13.683 に答える