Я пытаюсь загрузить свой список с данными из моей базы данных. И данные будут периодически обновляться.
<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";
}
}
Итак, как он мог перезагружать данные асинхронно, я не хочу обновлять страницу.
Мне нужно, чтобы он был в цикле, чтобы я мог слушать базу данных, и если есть новая запись, она обновит список
Я знаю об ослеплении данных, но у меня очень мало опыта в этом, может ли кто-нибудь привести пример, который поможет мне в этом.
вы не можете обновить источник элементов из потока





Поскольку 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
@SirRufo - Спасибо, я обновил свой ответ для AddRange.
Добавьте новые данные в исходную коллекцию с помощью диспетчера:
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
и использует кнопку для запуска функции обновления
Есть ли особая причина, по которой вы не используете шаблон MVVM?