Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用后台工作程序将文本文件插入列表框WPF_C#_Wpf_Data Binding - Fatal编程技术网

C# 使用后台工作程序将文本文件插入列表框WPF

C# 使用后台工作程序将文本文件插入列表框WPF,c#,wpf,data-binding,C#,Wpf,Data Binding,当我在循环中添加这行代码时 myCollection.Add(new FetchData(line)); 它抛出 此类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection 我也尝试过使用这个,但没有成功: mqttUpload.ItemsSource = MyList; 进度条会更新,我也可以打印行,唯一的问题是我无法将数据添加到列表框 这是我的数据在txt文件中的样子,该文件包含3500行。 这是我试过的 public pa

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

myCollection.Add(new FetchData(line)); 
它抛出

此类型的CollectionView不支持从不同于Dispatcher线程的线程更改其SourceCollection

我也尝试过使用这个,但没有成功:

mqttUpload.ItemsSource = MyList;
进度条会更新,我也可以打印行,唯一的问题是我无法将数据添加到列表框

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

这是我试过的

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;
    }
}
下面是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文件读取。
为什么不等到作业完成呢

您可以通过ReportsProgress发送数据


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

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

您的
Mylist.Add(行)违反了这条规则

您也可以使用进度事件:

  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
}

我以前也能将数据输入MyList,唯一的问题是我不能将数据添加到列表框中。我相信这将通过使用ObservableCollection来实现,我取代了Mylist.Add(line);添加(新的FetchData(行));使用您的代码,我的gui冻结。也不起作用。那
FetchData
不可能改变任何东西。我的代码不应该冻结,肯定还有一些你没有发布的东西。但这里最好的事情是避免这种情况:没有用户可以或想要读取3500行。你的GUI不是你的数据层。我不介意等到作业完成,但最后它应该会在GUI的列表框中显示数据。然后在jobFinished中执行。这听起来像是一个XY问题。真正的问题是,需要完成的99.9%的实际CPU工作必须发生在UI线程上:即呈现列表视图中显示行的所有控件。您无法真正显示UI呈现工作的进度条。您最好的选择是虚拟化。您应该简单地避免进行所有不必要的渲染,这样就不需要进度条,因为您的UI会立即加载
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
}