Sto riscontrando un problema con il recupero dati da db e la visualizzazione in UI in modo asincrono. Sto usando luce MVVM, quando si fa clic sul pulsante, azione viene attivata in ViewModel:Aggiornamento dell'interfaccia utente asincrona da ViewModel in WPF
private void SearchQuery(string query)
{
_redisModel.GetFriendsListAsync(query);
}
Ad un certo punto GetFriendsListCompleted viene chiamato dal thread in background notifing ViewModel che lavoro è fatto. A questo punto ho bisogno di aggiornare ListBox ItemSource. Ma quando provo ad aggiornare è ottengo “Il thread chiamante non può accedere a questo oggetto perché un thread diverso lo possiede” ho cercato Dispatcher.CurrentDispatcher.Invoke(), App.Current.Dispatcher.Invoke() e magie diverse, ma ancora non funziona.
Ho provato a fornire a UI il dispatcher a ViewModel e quindi a chiamare da lì - non ha funzionato.
private string filterText = string.Empty;
public string FilterText
{
get { return filterText; }
set
{
filterText = value;
this.RaisePropertyChanged(() => this.FilterText);
this.FriendsList.View.Refresh(); // Here where exception is happening.
}
}
Ho provato a cambiare questa riga per
Dispatcher.Invoke (DispatcherPriority.Normal, nuova azione ( () => this.FriendsList.View.Refresh())); - ancora lo stesso.
Sto usando Telerik ListBox per visualizzare gli elementi. FriendList è CollectionViewSource (http://www.telerik.com/help/wpf/radlistbox-overview.html). Funziona quando uso l'esempio Telerik dagli esempi di controllo WPF. I problemi iniziano a verificarsi quando utilizzo i miei metodi asincroni. Il tipo di visualizzazione è System.ComponentModel.ICollectionView è utilizzato per il filtro e il raggruppamento.
Ho anche provato ad assegnare ObservableCollection alla proprietà Items del ListBox e non funziona neanche.
un po 'più dettagli su come funziona _redisModel.GetFriendsListAsync: Alla fine (dopo tutta la catena di chiamate) si finisce qui:
public GetAsyncResult(Func<T> workToBeDone, Action<IAsyncResult> cbMethod, Object state)
{
_cbMethod = cbMethod;
_state = state;
QueueWorkOnThreadPool(workToBeDone);
}
ThreadPool.QueueUserWorkItem(state =>
{
try
{
_result = workToBeDone();
}
catch (Exception ex)
{
_exception = ex;
}
finally
{
UpdateStatusToComplete(); //1 and 2
NotifyCallbackWhenAvailable(); //3 callback invocation
}
});
In viewmodel ho metodo:
private void GetFriendsListCompleted(object sender, ResultsArgs<Friend> e)
{
if (!e.HasError)
{
var curr = e.Results;
if (curr != null)
{
this.FriendsList= new CollectionViewSource();
this.FriendsList.Source = list;
this.FriendsList.Filter += this.FriendFilter;
FilterText = "";
Dispatcher.Invoke(DispatcherPriority.Normal, new Action(
() => this.FriendsList.View.Refresh()));
}
}
Qualcuno può aiutarmi per favore con questo? Grazie
@ Robert Kruszewski – LucasSeveryn
modificare la tua domanda e aggiungere un po contesto alla tua domanda. Qual è il tipo di 'FriendsList'. Qual è la proprietà 'View' a cui stai accedendo dalla VM? – Viv