载入画面动画口吃

时间:2012-10-27 21:02:13

标签: wpf c#-4.0

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

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

当我开启虚拟化时,渲染提升到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;
    }

1 个答案:

答案 0 :(得分:0)

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

这实际上是一个闪屏。