Асинхронная загрузка ListView

Я пытаюсь загрузить свой список с данными из моей базы данных. И данные будут периодически обновляться.

<ListView Margin = "10" Name = "lvDataBinding" ></ListView> //frontend

Сейчас я экспериментирую с использованием backgroundworker для загрузки новых данных, но мне не повезло.

     <ListView Margin = "10" Name = "lvDataBinding" ></ListView> //frontend

    ObservableCollection<string> mNames = new ObservableCollection<string>(); 


public SettingsControl()
            {
                InitializeComponent();

                listview1.ItemsSource = mNames;
                mNames.Add("1");
                var mWorker = new BackgroundWorker();
                mWorker.DoWork += Worker_ListenForNewSMS;
                mWorker.RunWorkerAsync();


        }

    private void Worker_ListenForNewSMS(object sender, DoWorkEventArgs e)
            {
                while (true)
                {
                    Thread.Sleep(2000);
                    //fetch and load new data here, cant seems to work
                   listview1.ItemsSource = "NEWDATA";


                }
            }

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

Мне нужно, чтобы он был в цикле, чтобы я мог слушать базу данных, и если есть новая запись, она обновит список

Я знаю об ослеплении данных, но у меня очень мало опыта в этом, может ли кто-нибудь привести пример, который поможет мне в этом.

Есть ли особая причина, по которой вы не используете шаблон MVVM?

Sir Rufo 21.05.2018 07:04

вы не можете обновить источник элементов из потока

Shivani Katukota 21.05.2018 07:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
963
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Поскольку ItemsSource из ListView уже настроен, поэтому лучший способ обновить данные, используя приведенный ниже код:

mNames.Clear();
// Now add the ite,
mNames.Add("item1");
mNames.Add("item2");

Дополнительные сведения

Вы реализуете метод AddRange в ObservableCollection, поэтому несколько описанных выше состояний можно преобразовать в mNames.AddRange(<Collection Object>). Следуйте этому ссылка на сайт, чтобы реализовать AddRange.

// Альтернативное решение

Если вы попытаетесь обновить ItemsSource, вам следует обновить представление вручную. Предположим, вам нужно обновить его ОДИН раз после того, как ВСЕ элементы были добавлены в ItemsSource), поэтому вам следует использовать этот подход:

// Create the view.
ICollectionView view = CollectionViewSource.GetDefaultView(mNames);

// To Refresh calls like this.
view.Refresh();

Я бы предпочел вариант 1.

ObservableCollection не знает об AddRange

Sir Rufo 21.05.2018 07:03

@SirRufo - Спасибо, я обновил свой ответ для AddRange.

user1672994 21.05.2018 07:11

Добавьте новые данные в исходную коллекцию с помощью диспетчера:

private void Worker_ListenForNewSMS(object sender, DoWorkEventArgs e)
{
    while (true)
    {
        Thread.Sleep(2000);
        Dispatcher.BeginInvoke(new Action(() =>
        {
            mNames.Add("NEWDATA");
        }));
    }
}

Диспетчер направляет вызов обратно в поток пользовательского интерфейса. Это необходимо, поскольку вы можете обновлять коллекцию с привязкой к данным только в потоке пользовательского интерфейса (если вы не используете метод BindingOperations.EnableCollectionSynchronization).

Вам также необходимо использовать диспетчер, если вы по какой-то причине повторно устанавливаете свойство ItemsSource:

private void Worker_ListenForNewSMS(object sender, DoWorkEventArgs e)
{
    while (true)
    {
        Thread.Sleep(2000);
        Dispatcher.BeginInvoke(new Action(() =>
        {
            listview1.ItemsSource = new List<string> { "NEWDATA" };
        }));
    }
}

Вы не могу устанавливаете свойство элемента управления пользовательского интерфейса из фонового потока.

Ответ принят как подходящий

В конце я загружаю список с помощью observableCollection

и использует кнопку для запуска функции обновления

Другие вопросы по теме