Je souhaite mettre à jour mon interface utilisateur. Dois-je utiliser BackgroundWorker? Est-ce que je mets le BackgroundWorker dans MainWindowViewModel et instancie les dépôts de nouveau, ou est-ce que je le mets dans le OrdersQueueViewModel et fais quelque chose avec les propriétés?Les collections de mises à jour de MVVM WPF pour mettre à jour l'interface utilisateur
L'interface utilisateur affiche simplement le contenu des listes créées par LINQ. Les listes sont ObservableCollection
et sont les propriétés de OrdersQueueViewModel. J'ai un ViewModel MainWindowViewModel qui crée une collection ViewModels, de sorte que je peux lier à cette collection à partir de MainWindow.xaml (vue).
MainWindowViewModel.cs:
public MainWindowViewModel()
{
_printQueueRepos = new OrdersPrintQueueRepository();
_holdQueueRepos = new OrdersHoldQueueRepository();
_linesToPickRepos = new LinesToPickRepository();
_linesPerHourRepos = new LinesPerHourRepository();
//create an instance of viewmodel and add it to the collection
OrdersQueueViewModel viewModel = new OrdersQueueViewModel(_printQueueRepos, _holdQueueRepos, _linesToPickRepos, _linesPerHourRepos);
this.ViewModels.Add(viewModel);
}
MainWindow.xaml:
<Window.Resources>
<DataTemplate DataType="{x:Type vm:OrdersQueueViewModel}">
<vw:OrdersQueueView></vw:OrdersQueueView>
</DataTemplate>
</Window.Resources>
Exemple d'une propriété dans le OrderQueueViewModel qui utilise un référentiel:
public ObservableCollection<LinesToPick> LinesToPick
{
get
{
return new ObservableCollection<LinesToPick>(_linesToPickRepos.GetLinesToPick());
}
}
J'ai LinesToPick
lié dans le OrdersQueueView, et que la base de données met à jour les listes devrait c changer dans l'interface utilisateur. J'ai passé un peu de temps à lire sur BackgroundWorker, mais je ne sais pas trop quoi faire pour mettre à jour les listes. J'espère parce qu'ils sont ObservableCollections
je peux juste les «actualiser» et ils emploieront INotifyPropertyChanged et mettront à jour l'interface utilisateur automatiquement. Très nouveau à tout cela, en essayant de comprendre, merci d'avance pour toute aide.
EDIT: En utilisant la suggestion de James, je me suis retrouvé avec ceci dans mon OrdersQueueViewModel. Cependant, je reçois l'erreur "Ce type de CollectionView ne prend pas en charge les modifications apportées à sa SourceCollection à partir d'un thread différent du thread Dispatcher", lorsque le code arrive à .Clear() sur les 2 listes, ce qui est ce que je pensais expéditeur a été utilisé pour. Aucune suggestion?
Action workAction = delegate
{
_worker = new BackgroundWorker();
_worker.DoWork += delegate
{
LinesThroughput.Clear();
LinesToPick.Clear();
//refresh LinesToPick
foreach (var item in _linesToPickRepos.GetLinesToPick())
{
LinesToPick.Add(item);
}
//refresh LinesThroughput
List<LinesThroughput> Lines = new List<LinesThroughput> (_linesPerHourRepos.GetLinesThroughput());
foreach (var item in GetLinesThroughput(Lines))
{
LinesThroughput.Add(item);
}
};
_worker.RunWorkerAsync();
};
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, workAction);
Ma question originale a été répondue, je ne voulais pas vraiment commencer un nouveau fil, j'espère que vous savez peut-être être en mesure de me diriger dans la bonne direction sur cette nouvelle partie. – LobalOrning
Vous avez votre code Dispatcher à l'envers. Vous voulez appeler le répartiteur à l'intérieur de BackgroundWorker, et non l'inverse. BTW - Mon code Refresh() est un peu naïf. Vous devriez vraiment aller chercher la liste des nouveaux éléments sur le thread d'arrière-plan et les passer dans Refresh (newItems) plutôt que d'appeler le repo depuis Refresh. –