使用后台工作器将文本文件插入到listBox WPF中

时间:2018-06-23 15:37:37

标签: c# wpf data-binding

当我在循环内添加这一行代码

myCollection.Add(new FetchData(line)); 

它抛出

  

这种CollectionView不支持从与Dispatcher线程不同的线程对其SourceCollection进行更改

我也尝试过使用它,但是没有用:

mqttUpload.ItemsSource = MyList;

进度条将更新,我也能够打印行,唯一的问题是我无法将数据添加到列表框。

这是我的数据在txt文件中的样子,该文件包含3500行。 enter image description here

这是我尝试过的。

public partial class UserControl2 : UserControl
{

    public static List<string> Mylist = new List<string>();
    ObservableCollection<FetchData> myCollection = new  ObservableCollection<FetchData>();

    public UserControl2()
    {
        InitializeComponent();
        mqttUpload.ItemsSource = myCollection;

        backgroundWorker1.DoWork += backgroundWorker1_DoWork;
        backgroundWorker1.ProgressChanged +=backgroundWorker1_ProgressChanged;
        backgroundWorker1.WorkerReportsProgress = true;
        backgroundWorker1.RunWorkerCompleted += jobfinish;

    }

    public static UserControl2 uploadData;

    BackgroundWorker backgroundWorker1 = new BackgroundWorker();
    public static string FilePath = "";

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        var files = File.ReadAllLines(FilePath);
        for (int i = 0; i < files.Length; i++)
        {
            var line = files[i];
            Mylist.Add(line);
            int percentage = (int)((i / (double)files.Length) * 100.0);
            backgroundWorker1.ReportProgress(percentage);
            Console.WriteLine(line);
        }
    }

    public void jobfinish(object sender, RunWorkerCompletedEventArgs e)
    {
        Console.WriteLine(  "finish");

    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)// progress change
    {
        progressBar1.Value = e.ProgressPercentage;
    }
}

获取类

public class FetchData
{
    public string fetchData { get; set; }

    public FetchData(string fetchData)
    {
        this.fetchData = fetchData;
    }
}

这是XAML代码

<ListBox Margin="10,64,0,-434" Grid.Column="2" Name="mqttUpload" 
         Padding="20,0,0,0" Background="#18191A"  Foreground="#F5980C" Grid.Row="2" />

我的目标是在显示进度条的同时逐行读取数据,最后在ListBox中显示数据。

这就是应该在列表框中显示数据的方式。在此图像中,我正在从数据库中读取数据。我想实现相同的目的,但要从txt文件读取。 enter image description here

2 个答案:

答案 0 :(得分:2)

最重要的规则:您只能从GUI(主)线程中触摸GUI。

您的Mylist.Add(line);违反了该规则。

您也可以使用Progress事件:

  backgroundWorker1.ReportProgress(percentage, line);

然后

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)// progress change
{
   progressBar1.Value = e.ProgressPercentage;
   string line = (string) e.State;
   Mylist.Add(line);  // ok, this runs on the main thread
}

答案 1 :(得分:0)

为什么不等到jobFinished完成?

您可以通过ReportsProgress发送数据。

BackgroundWorker.ReportProgress Method (Int32, Object)

一次将UI更新一行会带来很多开销。我将使用异步文件IO并读取前100行,然后读取整个文件。