Рабочий стол Winui3; ObservableCollection, обновление пользовательского интерфейса при изменении свойства? Обновление изC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Рабочий стол Winui3; ObservableCollection, обновление пользовательского интерфейса при изменении свойства? Обновление из

Сообщение Anonymous »

Это небольшое тестовое приложение, позволяющее попытаться решить эту проблему с помощью моего основного приложения. Сначала я вставлю код.
XAML: ViewModel (MainViewModel.cs):

Код: Выделить всё

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);
}
}
}
BindableBase.cs:

Код: Выделить всё

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;
}

}
}
PositionModel.cs:

Код: Выделить всё

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; }
}
}
PositionsClass.cs:

Код: Выделить всё

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);
}
}
}
}
По сути, вы нажимаете кнопку «Добавить в список», после чего создается PositionsClass PositionsClass, создается и заполняется PositionModel _position, создается ObservableCollection PositionCollection (с привязкой к просмотру списка в xaml), затем выделите класс в отдельный поток. Класс получит _position и увеличит свой .Place, а затем Progress.Report _position обратно в основной поток.
Теперь я пытаюсь выяснить, как получить PositionCollection (из ObservableCollection), чтобы обновить пользовательский интерфейс lisview. Я подписался на Progress.ProgressChanged и обновил выходную строку, просто чтобы убедиться, что класс действительно работает и увеличивается, что действительно работает.
Я пробовал разные вещи, которые я пробовал найдены в Интернете, включая различные унаследованные методы ObversableCollection, ни один из которых не работает, или я их неправильно понял.
Я думал реализовать INotifyPropertyChange на Сама PositionModel будет работать (закомментированный код), но при этом возникает перекрестная ошибка. Я предполагаю, что это потому, что PositionClass в отдельном потоке обновляет .Place, что вызывает ошибку перекрестного потока?
Может ли кто-нибудь помочь объяснить, как получить ObservableCollection для обновить пользовательский интерфейс, когда его свойства изменяются в моем примере выше? Спасибо! В моем основном приложении я буду обновлять множество свойств в отдельном потоке, а не только два в этом примере. Вот почему я подумал, что будет проще просто отправить всю модель обратно в отчете о прогрессе.

Подробнее здесь: https://stackoverflow.com/questions/714 ... es-updatin
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»