2012-10-27 2 views
1

로딩 애니메이션을 표시하는 동안 배경 작업자를 사용하여 매우 큰 세트의 세트를로드합니다. 실행 작업 완료 이벤트에서로드 된 모든 항목을 관찰 가능한 모음으로 설정 한 다음로드 화면을 전환합니다. 문제는 항목이 관찰 가능한 컬렉션으로 설정 될 때까지 진행 막대가 부드럽게 움직이는 것입니다. 그러면 애니메이션이 중지됩니다. 이러한 항목의 렌더링이 애니메이션을 방해하기 때문에 이것이라고 상상해보십시오. 렌더링 단계에서 애니메이션을 부드럽게 만들 수있는 방법이 있습니까? 응용 프로그램을 실행할 때 내가 할 시간은 다음과 같습니다로딩 스크린 애니메이션 스터 터

로드 = 1000 MS
속성 설정 = 43 MS
렌더링 = 5083 MS

I가 가상화 켤 때 렌더링이 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; 
    } 

답변

0

한 가지 방법은 다른 UI 스레드에서 실행되는 현재 윈도우의 상단에 오버레이 창을 생성하고 로딩 애니메이션이 창에 표시하고로드의 창 모양 부분을 확인하기 위해 적절한 속성을 설정입니다 창문.

이것은 본질적으로 스플래시 화면입니다.

관련 문제