XAML:
Код: Выделить всё
Код: Выделить всё
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.UI.Dispatching;
using Windows.UI.Core;
using Windows.ApplicationModel;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ThreadTest {
public class MainViewModel : BindableBase, INotifyPropertyChanged {
private String outputString = "Empty";
public MainViewModel() {
}
public String OutputString {
get { return outputString; }
set { SetProperty(ref outputString, value); }
}
private Random _random = new Random();
private int _id = 0;
private ObservableCollection
_positioncollection = new();
public ObservableCollection PositionCollection {
get { return _positioncollection; }
set { SetProperty(ref _positioncollection, value); }
}
public async void AddPosition() {
Progress progress = new();
progress.ProgressChanged += Progress_ProgressChanged;
// Increase id for each new position added.
_id++;
// Setup/
var _position = new PositionModel {
ID = _id,
Place = _random.Next(1, 1000), // Get a random starting point.
};
PositionCollection.Add(_position);
PositionsClass positionsClass = new(ref _position, progress);
await Task.Run(() => { positionsClass.Start(); });
}
private void Progress_ProgressChanged(object sender, PositionModel e) {
// This is so I can see that the thread is actually running.
OutputString = Convert.ToString(e.Place);
}
}
}
Код: Выделить всё
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace ThreadTest {
public class BindableBase : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty(ref T originalValue, T newValue, [CallerMemberName] string propertyName = null) {
if (Equals(originalValue, newValue)) {
return false;
}
originalValue = newValue;
OnPropertyChanged(propertyName);
return true;
}
}
}
Код: Выделить всё
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace ThreadTest {
public class PositionModel {
/*
// Implement INotifyPropertyChanged up above if using this.
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetProperty(ref T originalValue, T newValue, [CallerMemberName] string propertyName = null) {
if (Equals(originalValue, newValue)) {
return false;
}
originalValue = newValue;
OnPropertyChanged(propertyName);
return true;
}
private int _id = 0;
public int ID {
get { return _id; }
set { SetProperty(ref _id, value); }
}
private int _place = 0;
public int Place {
get { return _place; }
set { SetProperty(ref _place, value); }
}
*/
public int ID { get; set; }
public int Place { get; set; }
}
}
Код: Выделить всё
using Microsoft.UI.Dispatching;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ThreadTest {
public class PositionsClass {
private IProgress
_progress;
private PositionModel _position;
public PositionsClass(ref PositionModel position, IProgress progress) {
_progress = progress;
_position = position;
}
public void Start() {
StartFakePosition();
}
private void StartFakePosition() {
// Just using a quick loop to keep the numbers going up.
while (true) {
_position.Place++;
// Send position back.
_progress.Report(_position);
Thread.Sleep(100);
}
}
}
}
Теперь я пытаюсь выяснить, как получить PositionCollection (из ObservableCollection), чтобы обновить пользовательский интерфейс lisview. Я подписался на Progress.ProgressChanged и обновил выходную строку, просто чтобы убедиться, что класс действительно работает и увеличивается, что действительно работает.
Я пробовал разные вещи, которые я пробовал найдены в Интернете, включая различные унаследованные методы ObversableCollection, ни один из которых не работает, или я их неправильно понял.
Я думал реализовать INotifyPropertyChange на Сама PositionModel будет работать (закомментированный код), но при этом возникает перекрестная ошибка. Я предполагаю, что это потому, что PositionClass в отдельном потоке обновляет .Place, что вызывает ошибку перекрестного потока?
Может ли кто-нибудь помочь объяснить, как получить ObservableCollection для обновить пользовательский интерфейс, когда его свойства изменяются в моем примере выше? Спасибо! В моем основном приложении я буду обновлять множество свойств в отдельном потоке, а не только два в этом примере. Вот почему я подумал, что будет проще просто отправить всю модель обратно в отчете о прогрессе.
Подробнее здесь: https://stackoverflow.com/questions/714 ... es-updatin