在执行操作时动态地在文本框中写入文本

时间:2014-01-15 12:09:19

标签: c# .net wpf

我在.NET中有简单的WPF格式,允许mw选择目录,然后对其中的文件执行某些操作

我有按钮,它触发动作(它将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”)?

3 个答案:

答案 0 :(得分: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();
        }
    }
}

答案 1 :(得分:0)

这种情况正在发生,因为您的操作是同步的。在另一个线程中提取处理文件操作。如果您使用的是.NET 4.5+,请尝试在方法中添加异步字:

private async void processButton_Click(object sender, RoutedEventArgs e)

答案 2 :(得分:0)

您可以让“Click”事件调用另一个处理此逻辑的方法,以尽快结束此方法。

否则,只需简单地解决您已有的问题就可以获得更新日志信息的方法。

例如:

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

这样,使用循环,您可以报告处理的文件数。您可以在块中执行此操作以避免垃圾邮件。

你的for循环,有建议:

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");