代码之家  ›  专栏  ›  技术社区  ›  Jo Joy

使用后台工作进程将文本文件插入列表框wpf

  •  2
  • Jo Joy  · 技术社区  · 6 年前

    当我在循环中添加这行代码时

    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" />
    

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

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

    2 回复  |  直到 6 年前
        1
  •  2
  •   Henk Holterman    6 年前

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

    你的 Mylist.Add(line); 是在违反规则。

    您也可以使用进度事件:

      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
    }
    
        2
  •  0
  •   paparazzo    6 年前

    为什么不等到工作完成呢?

    您可以通过ReportsProgress发送数据。

    BackgroundWorker.ReportProgress Method (Int32, Object)

    更新UI一行一段时间开销很大。我将使用异步文件IO,读取前100行,然后读取整个文件。