更新: datatemplate の 2 つの行が速度を落としているようです。この 2 行だけをコメントアウトすると、つまり
<Image Source="{Binding IconSelect}" Width="20" Height="20" />
と
<Image Source="{Binding IconBaseAcctFlag}" Width="20" Height="20" />
それは正常に動作します。リストがリストビューにレンダリングされているときに、これらの画像をデータテンプレートに含めるとGUIがフリーズする理由はありますか?
2 つのパネルを含むフォームがあります。左側はツリー ビューで、行をクリックすると、このエンティティに対応するデータが取得され、右側にリスト ビューで表される概要ペインが作成されます。
バックグラウンド スレッドでデータを取得して処理し、最終呼び出しで Application.Current.Dispatcher.Invoke() を使用して、ListView の ItemsSource プロパティを作成したコレクションに設定します。これにより、非常に応答性の高い GUI が維持されると予想していましたが、ItemsSource プロパティの更新時に、これが行われている間に GUI が約 1.5 秒間フリーズし、なぜこれほど時間がかかるのかわかりません。
また、最初に空の ObservableCollection をバインドしてから、コレクションに追加するたびにディスパッチャを呼び出してみました。これにより応答性が少し向上しますが、パネルは 1 行ずつ読み込まれますが、それでも私が望むパフォーマンスではありません。さらに、コードは非常に多くのディスパッチャ呼び出しで非常に厄介になります。
ここで何が問題なのか誰にも提案できますか? 確かに、約 12 ~ 20 個のエントリを持つ汎用コレクションをリストビューにバインドして、ほぼ瞬時に更新することができますか?
public void DisplayAcctSummary(RbcUIAccount selAcct)
{
if (selAcct == null)
{
ClearBaseAcctTransSummary();
return;
}
InvokeUpdate(() => gbBaseDetails.Header = "Account Details");
InvokeUpdate(() => lvBaseAccountDetails.ItemsSource = null);
SelBoolValueForSelectedQueue();
var lstBaseAcctDetails = new ObservableCollection<RbcUIBaseAcctDetails>();
if (selCustSummary != null)
{
var offsetAllowed = IsOffselAllowed(selAcct.Branch);
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Account No:", selAcct.AccountId));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Account Name:", selAcct.AcctDesc));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Account Type:", ((RbcEnums.AccountType)selAcct.AccountType).ToString()));
if (selAcct.Branch != string.Empty)
{
var rbcBranch = RbcStaticData.GetBranchbyID(selAcct.Branch.Trim());
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Branch:", rbcBranch.BranchName));
}
if (!IsInCURView && !IsInCURPendingView)
{
var serviceLayer = new RbcServiceLayer();
var account = serviceLayer.GetAccountById(selAcct.AccountId, UserSession.SecurityContext);
if (account != null)
{
if (account.BaseId != string.Empty)
{
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Current Balance:", selAcct.CurrentBalance, false, selAcct.DisplayUSDRate));
if (!offsetAllowed || (IsInCCMPView) || (IsInCCMPPendingView))
{
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Available Balance:", selAcct.AvailableBalance, false, selAcct.DisplayUSDRate));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Available Funds:", selAcct.AvailableFunds, false, selAcct.DisplayUSDRate));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Base Sublimit:", rbcUtils.DisplayAmount(selAcct.BaseSublimit)));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Available Funds SL:", selAcct.AvailableFundsSL, false, selAcct.DisplayUSDRate));
}
if (!IsInCustomerEnquiryView && !offsetAllowed)
{
var excessToday = new RbcMoney();
var totAwtToday = SumTotalAwtForAccount(selAcct.AccountId);
var totAwtAllDates = SumTotalAwtAllDatesForAccount(selAcct.AccountId);
excessToday.Amount = totAwtToday.Amount - selAcct.AvailableFunds.Amount;
excessToday.Currency = totAwtToday.Currency;
if (excessToday.Amount < 0)
excessToday.Amount = 0;
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Total Awaiting Today:", new RbcMoney(Math.Round(totAwtToday.Amount), totAwtToday.Currency), false, selAcct.DisplayUSDRate));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Total Excess Today:", new RbcMoney(Math.Round(excessToday.Amount), excessToday.Currency), false, selAcct.DisplayUSDRate));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Total Awaiting All Dates:", new RbcMoney(Math.Round(totAwtAllDates.Amount), totAwtAllDates.Currency), false, selAcct.DisplayUSDRate));
if (customer.Category != Convert.ToByte((CustCategory.Today)))
{
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Total Awaiting Future:", selAcct.TotalAwaitingToday, false, selAcct.DisplayUSDRate));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Total Excess Future:", selAcct.TotalExcessToday, false, selAcct.DisplayUSDRate));
}
}
}
else
{
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Current Balance", selAcct.CurrentBalance, false, selAcct.DisplayUSDRate));
if (!offsetAllowed && account.BaseId != string.Empty)
{
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Available Balance:", selAcct.AvailableBalance, false, selAcct.DisplayUSDRate));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Available Funds:", selAcct.AvailableFunds, false, selAcct.DisplayUSDRate));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Available Funds SL:", selAcct.AvailableFundsSL, false, selAcct.DisplayUSDRate));
}
}
}
if (IsInCCMPView || IsInCCMPPendingView)
{
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails(AppString.CustomerSummary.EarmarkPaymentDate, "0", true, string.Empty));
}
}
if (!IsInCURView && !IsInCustomerEnquiryView)
{
var txnCount = 0;
double totAmount = 0;
RbcUITransaction transaction;
foreach (var t in selAcct.Transactions)
{
transaction = t;
var amount = rbcUtils.GetAmountInCustomerCurency(transaction.Amount.Amount, transaction.Amount.Currency, customer.CustCurrencyId);
totAmount += amount;
txnCount++;
}
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("No of Txns:", txnCount.ToString()));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Value of Txns:", new RbcMoney(totAmount, customer.CustCurrencyId), false, true));
lstBaseAcctDetails.Add(new RbcUIBaseAcctDetails("Last updated at:", selAcct.LastUpdatedAt.ToString("dd-MM-yyyy HH:mm") + " GMT"));
}
}
InvokeUpdate(() => lvBaseAccountDetails.ItemsSource = lstBaseAcctDetails);
}
更新: ListView の XAML は次のとおりです。
<ListView x:Name="lvBaseAccountDetails" Margin="10,10,10,10" Background="#F4F8FB" ItemsSource="{Binding}" MouseDoubleClick="lvBaseAccountDetails_MouseDoubleClick" ItemContainerStyle="{StaticResource myHeaderStyleColor}">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridView.Columns>
<GridViewColumn Header="" >
<GridViewColumn.CellTemplate>
<DataTemplate >
<Grid>
<Image Source="{Binding IconSelect}" Width="20" Height="20" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="200" Header="" DisplayMemberBinding="{Binding SubBaseAcctType}" >
</GridViewColumn>
<GridViewColumn Width="200" Header="" DisplayMemberBinding="{Binding SubBaseAcctValue}">
</GridViewColumn>
<GridViewColumn Header="" >
<GridViewColumn.CellTemplate>
<DataTemplate >
<Grid>
<Image Source="{Binding IconBaseAcctFlag}" Width="20" Height="20" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>