1

我在显示加载动画时使用后台工作程序加载大量项目。在 run worker 完成事件中,我将所有这些加载的项目设置为一个可观察的集合,然后关闭加载屏幕。问题是进度条动画流畅,直到项目设置为可观察集合,然后它才停止动画。我想这是因为这些项目的渲染会干扰动画。在渲染阶段有什么方法可以使动画平滑吗?运行应用程序时,我得到的时间是:

加载 = 1000 毫秒
设置属性 = 43 毫秒
渲染 = 5083 毫秒

打开虚拟化后,渲染时间提高到 19 毫秒。我将其关闭以演示渲染时间较长的场景。

    public ObservableCollection<string> Items { get; set; }
    private IEnumerable<string> _items;
    private BackgroundWorker _worker;
    private long _loadTime;
    private long _renderTime;
    private long _setPropertiesTime;

    public MainWindow()
    {
        InitializeComponent();
        Items = new ObservableCollection<string>();
        _itemsGrid.DataContext = this;
        _worker = new BackgroundWorker();
        _worker.DoWork += DoWork;
        _worker.RunWorkerCompleted += RunWorkerCompleted;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        _renderLabel.Content = string.Empty;
        _loadLabel.Content = string.Empty;
        _loadingBorder.Visibility = Visibility.Visible;
        _worker.RunWorkerAsync();            
    }

    void DoWork(object sender, DoWorkEventArgs e)
    {
        _items = LoadItems();            
    }

    void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        var setItemsTimer = Stopwatch.StartNew();
        Items.Clear();

        foreach (var item in _items)
        {
            Items.Add(item);
        }

        setItemsTimer.Stop();
        _setPropertiesTime = setItemsTimer.ElapsedMilliseconds;

        var timer = Stopwatch.StartNew();

        Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => 
        {
            timer.Stop();
            _loadLabel.Content = string.Format("Loading took {0} ms, Set properties took {1} ms", _loadTime, _setPropertiesTime);
            _renderLabel.Content = string.Format("Rendering took {0} ms", timer.ElapsedMilliseconds);
            _loadingBorder.Visibility = Visibility.Collapsed;
        }));
    }

    IEnumerable<string> LoadItems()
    {
        var timer = Stopwatch.StartNew();
        var items = new List<string>();
        for (int i = 0; i < 5000; i++)
        {
            items.Add("Testing");
        }

        Thread.Sleep(1000);

        timer.Stop();
        _loadTime = timer.ElapsedMilliseconds;
        return items;
    }
4

1 回答 1

0

一种方法是在当前窗口之上创建一个覆盖窗口,该窗口在不同的 UI 线程下运行,并在此窗口中显示加载动画,并设置适当的属性以使窗口看起来是加载窗口的一部分。

这本质上是一个闪屏。

于 2012-11-11T21:47:11.310 回答