Использование фонового Worker для вставки текстового файла в listBox WPF - PullRequest
0 голосов
/ 23 июня 2018

Когда я добавляю эту строку кода в цикл

myCollection.Add(new FetchData(line)); 

бросает

Этот тип CollectionView не поддерживает изменения в его SourceCollection из потока, отличного от потока Dispatcher

Я также пытался использовать это, но не сработало:

mqttUpload.ItemsSource = MyList;

Обновляется индикатор выполнения, и я также могу печатать строки, единственная проблема в том, что я не могу добавить данные в ListBox.

Вот так выглядят мои данные в текстовом файле, этот файл содержит 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 голосов
/ 23 июня 2018

Самое важное правило: вы можете касаться 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
}
0 голосов
/ 23 июня 2018

Почему бы просто не подождать, пока jobFinished?

Вы можете отправлять данные через ReportsProgress.

Метод BackgroundWorker.ReportProgress (Int32, Object)

Обновление пользовательского интерфейса на линии, много времени. Я бы использовал асинхронный ввод-вывод файла и прочитал первые 100 строк, а затем прочитал весь файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...