WPF GUI无响应更新ListView

时间:2012-08-29 14:13:16

标签: c# wpf performance user-interface

更新:看起来datatemplate中的两行正在减慢速度。如果我只评论那两行,即

<Image Source="{Binding IconSelect}" Width="20" Height="20" />

<Image Source="{Binding IconBaseAcctFlag}" Width="20" Height="20" />

工作正常。在将列表呈现到列表视图时,知道为什么在datatemplate中使用这些图像会冻结GUI吗?

我有一个包含两个面板的表单。在左侧是树视图,当您单击一行时,它会检索此实体的相应数据,并在右侧构建一个摘要窗格,由列表视图表示。

我在后台线程上获取和处理数据,然后在最终调用中使用Application.Current.Dispatcher.Invoke(),将ListView的ItemsSource属性设置为我构建的集合。我本来希望这能维持一个非常灵敏的GUI,但在更新ItemsSource属性时,GUI会冻结大约1.5秒,而这种情况发生时我不知道为什么这么长时间。

我还尝试在开始时绑定一个空的ObservableCollection,然后在每次添加到集合时调用调度程序。这使得响应更快,但是面板逐行加载,它仍然不是我想要的性能,加上代码最终会因为这么多的调度程序调用而变得非常混乱。

有人可以在这里提出可能存在的问题吗?当然,您可以将具有大约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>

0 个答案:

没有答案