2014-01-15 40 views
0

我在.NET簡單的WPF的形​​式,它允許兆瓦選擇目錄,然後在其中Dynamicaly寫在文本框中的文本,而在執行動作

我有按鈕,觸發動作執行的文件的一些行動(這是將XML文件轉換爲csv)。這需要一些時間,所以我想寫入文本框的信息處理文件的數量等。

我可以這樣做,但所有郵件發送到文本框在Click行動完成後,顯示整個過程完成後。我想要的是在處理Click方法中的數據時將消息發送到文本框。

這是點擊觸發方法:

private void processButton_Click(object sender, RoutedEventArgs e) 
{ 
     List<string> allXmlFiles = ProcessDirectory(selectedDir); 
     textbox.Text += String.Format("\n{0} files will be processed", allXmlFiles.Count); 
     if (allXmlFiles.Count > 0) 
     { 
      textbox.Text += "\nProcessing files..."; 
      foreach (string filepath in allXmlFiles) 
      { 
       try 
       { 
        ParseFile(filepath); 
       } 
       catch 
       { 
        textbox.Text += String.Format("\nCannot process file {0}", filepath); 
       } 
      } 
     } 

     textbox.Text += "\nDone"; 
} 

我怎樣才能讓消息(「X文件將被處理」,「處理文件...」,「無法處理文件XYZ」)同時出現計算而不是之後?

+0

看起來有一種方法,當一個TextBox更新控制。我無法測試這個,所以我不會提供它作爲答案,但試試吧:http://msdn.microsoft.com/en-us/library/ms754356.aspx – esel

回答

1

這一點,因爲你正在同步開始您的分析,以克服你的問題,嘗試BackgroundWorker的像這樣的東西

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.ComponentModel; 

namespace WpfApplication2 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     BackgroundWorker bckg = new BackgroundWorker(); 
     private List<string> allXmlFiles; 
     public MainWindow() 
     { 
      InitializeComponent(); 

      bckg.DoWork += new DoWorkEventHandler(bckg_DoWork); 
      bckg.ProgressChanged += new ProgressChangedEventHandler(bckg_ProgressChanged); 
      bckg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bckg_RunWorkerCompleted); 


     } 

     void bckg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if (e.Error!=null) 
      { 
       textbox.Text += String.Format("\nCannot process file {0}", filepath); 
      } 
     } 

     void bckg_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      //here you can update your textblox 

      Dispatcher.Invoke(() => 
       { 
        textbox.Text = e.UserState.ToString(); 
       }); 

     } 

     void bckg_DoWork(object sender, DoWorkEventArgs e) 
     { 
      allXmlFiles = ProcessDirectory(selectedDir); 
      if (allXmlFiles.Count > 0) 
      { 

       bckg.ReportProgress("here in percentage", "\nProcessing files..."); 
       foreach (string filepath in allXmlFiles) 
       { 
        try 
        { 
         ParseFile(filepath); 
        } 
        catch 
        { 
         throw; 
        } 
       } 
      } 

     } 

     private void button1_Click(object sender, RoutedEventArgs e) 
     { 

      textbox.Text += String.Format("\n{0} files will be processed", allXmlFiles.Count); 
      bckg.RunWorkerAsync(); 
     } 
    } 
} 
+0

太棒了! 工程就好了。我仍然有一些麻煩顯示進展,但問題解決了。 – Zbynek

+0

如果要使BackgroundWorker.ProgressChanged工作,BackgroundWorker.WorkerReportsProgress應設置爲true – vutran

0

發生這種情況是因爲您的操作是同步的。在另一個線程中提取您的處理文件操作。如果您正在使用.NET 4.5+,嘗試在方法加入異步字:

private async void processButton_Click(object sender, RoutedEventArgs e) 
0

你可以有你的'Click'事件調用另一個處理這個邏輯的方法來儘快結束這個方法。

否則,一個簡單的解決方法就是擁有一個方法來更新日誌信息。

例如:

UpdateText(String newText) 
{ 
    textBox.Text += "\r\n" + newText; 
} 

有了這個,使用循環,你可以報告處理的文件數量。你可以做到這一點大塊,以避免垃圾郵件。

您的循環,搭配建議:

int numProcessed = 0; 
foreach (string filepath in allXmlFiles) 
{ 
    try 
    { 
     ParseFile(filepath); 
     numProcessed++; // or you could use '++numProcessed' inline 

     if(numProcessed % 10 == 0 && numProcessed >= 10) 
      UpdatedText("Another 10 files processed!"); 
    } 
    catch 
    { 
     UpdateText(String.Format("\nCannot process file {0}", filepath)); 
    } 
} 
UpdatedText("Finished");