2011-06-14 19 views
7

WPF'de UI güncelleştirmesi ile ilgili bir sorun var.WPF öğeleri olay işleyicilerinde UI güncelleştirmesi

Böyle kod var:

private void ButtonClick_EventHandler(object sender, RoutedEventArgs e) 
    { 
     Label.Visibility = Visibility.Visible; 
     TextBox.Text = "Processing..."; 

     LongTimeMethod(); //some long operation 
    } 

sorun LongTimeMethod uçları kadar (yani olay işleyicisi biter) yani Label.Visibility ve TextBox.Text değişmeyecektir.

Ben şimdiye kadar bu gibi çözülür:

private void ButtonClick_EventHandler(object sender, RoutedEventArgs e) 
    { 
     Label.Visibility = Visibility.Visible; 
     TextBox.Text = "Processing..."; 

     Dispatcher.BeginInvoke(new Action(LongTimeMethod), 
      DispatcherPriority.Background); 
    } 

memuru çağırmayı kullanmadan başka bir çözüm var mı? This.UpdateLayout() yönteminin çağrılması yardımcı olmaz.

cevap

1

Görünürlük ve Metin, dağıtıcı tarafından güncellenen bağımlılık özellikleridir. Çözümünüz kesinlikle sıkı, ama önerim asenkron olarak yapmak.

Diğer taraftan, Application.DoEvents ürününü WPF'de (see the article) taklit edebilirsiniz.

+0

Bir neden var Application.DoEvents WPF içine getirilmedi! UI iş parçacığını serbest bırakmak istiyorsanız * UI iş parçacığı * 'nı serbest bırakmalısınız, beklemedeki iletileri işleyerek sahte değil –

+0

Paralelizme bağlıyız, sadece alternatif bir çözüm önerdim. –

4

Dispatcher.BeginInvoke ile hala LongTimeMethod() için UI iş parçacığı kullanıyorsunuz. Bu gerekli değilse ben bir arka plan iş parçacığı üzerinde çalıştırmak için TPL kullanarak öneririm (yani arka plan işleme çeşit yapıyor): Bu yöntemde

private void ButtonClick_EventHandler(object sender, RoutedEventArgs e) 
{ 
    Label.Visibility = Visibility.Visible; 
    TextBox.Text = "Processing..."; 

    Task.Factory.StartNew(() => LongTimeMethod()) 
     .ContinueWith(t => 
     { 
      Dispatcher.BeginInvoke((Action)delegate() 
      { 
       TextBox.Text = "Done!"; 
      }); 
     }); 

} 

, uzun koşu yöntemi bir arka plan üzerinde işlenir iş parçacığı (böylece UI iş parçacığı işleme devam etmek için serbest olacak ve uygulama donmayacak) ve arka plan görevi

tamamlandığında kullanıcı arabirimini (metin kutusu metnini güncelleştirmeyi gibi) değiştiren her şeyi yapabilir
+0

Bu durumda, bu yöntem, UI iş parçacığında çalışır. Ben sadece dağıtıcıları, iş parçacıkları, vb kullanmaktan kaçınmak istedim. –

+2

@brain_pusher, UI iş parçacığı uzun çalışma işlemini gerçekleştiriyorsa, ayarladığınız UI özelliklerini güncelleştirmek mümkün olmayacaktır. 'Dispatcher.BeginInvoke' kullanarak 'bunu kullanıcı arabiriminde yapın, ancak bunu yapmayın * hemen şimdi *; Mevcut görevlerinizi tamamladığınızda yapın. Bu yüzden güncellenmiş UI'yi görüyorsunuz –

+0

Yeni thread() ile arasındaki fark nedir? Start() '? – Alex78191

İlgili konular