Ce type de CollectionView ne prend pas en charge les modifications de son SourceCollection à partir d'un thread différent de l'expéditeur au fil
J'ai un DataGrid qui est le remplissage de données à partir de ViewModel par la méthode asynchrone.Mon DataGrid est :
<DataGrid ItemsSource="{Binding MatchObsCollection}" x:Name="dataGridParent"
Style="{StaticResource EfesDataGridStyle}"
HorizontalGridLinesBrush="#DADADA" VerticalGridLinesBrush="#DADADA" Cursor="Hand" AutoGenerateColumns="False"
RowDetailsVisibilityMode="Visible" >
Je suis en utilisant http://www.amazedsaint.com/2010/10/asynchronous-delegate-command-for-your.html à mettre en œuvre de façon asynchrone dans mon viewmodel.
Voici mon viewmodel code:
public class MainWindowViewModel:WorkspaceViewModel,INotifyCollectionChanged
{
MatchBLL matchBLL = new MatchBLL();
EfesBetServiceReference.EfesBetClient proxy = new EfesBetClient();
public ICommand DoSomethingCommand { get; set; }
public MainWindowViewModel()
{
DoSomethingCommand = new AsyncDelegateCommand(
() => Load(), null, null,
(ex) => Debug.WriteLine(ex.Message));
_matchObsCollection = new ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC>();
}
List<EfesBet.DataContract.GetMatchDetailsDC> matchList;
ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC> _matchObsCollection;
public ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC> MatchObsCollection
{
get { return _matchObsCollection; }
set
{
_matchObsCollection = value;
OnPropertyChanged("MatchObsCollection");
}
}
//
public void Load()
{
matchList = new List<GetMatchDetailsDC>();
matchList = proxy.GetMatch().ToList();
foreach (EfesBet.DataContract.GetMatchDetailsDC match in matchList)
{
_matchObsCollection.Add(match);
}
}
Comme vous pouvez le voir dans ma méthode Load() dans mon ViewModel d'abord, je suis matchList (qui est une liste de DataContract Classe) à partir de mon Service.Puis par la boucle foreach, je suis d'insérer ma matchList des articles à mon _matchObsCollection(qui est une ObservableCollection de DataContract Classe)).Maintenant, ici, j'obtiens l'erreur ci-dessus (comme je l'ai indiqué dans le Titre) "Ce type de CollectionView ne prend pas en charge les modifications de son SourceCollection à partir d'un thread différent de l'expéditeur au fil"
Quelqu'un peut-il me suggérer une solution.En outre, si possible, je voudrais savoir comment faire pour lier mon DataGrid en Vue et aussi l'actualiser de manière asynchrone si tout meilleure façon est là.
- La Solution ici : codeproject.com/Articles/64936/...
- merci pour le post en CodeProject..
- Pas de problème, je suis sûr qu'il va travailler pour vous. Merci de laisser des commentaires à la CodeProject lorsque vous obtenez une chance. Bonne chance!
Vous devez vous connecter pour publier un commentaire.
Depuis votre ObservableCollection est créé sur le thread de l'INTERFACE utilisateur, vous ne pouvez le modifier à partir de l'UI thread et pas des autres threads. Ce qui est considéré comme l'affinité de thread.
Si jamais vous avez besoin de mettre à jour les objets créés sur le thread de l'INTERFACE utilisateur de thread différent, il suffit de
put the delegate on UI Dispatcher
et qui va faire le travail pour vous déléguer cela à des thread de l'INTERFACE utilisateur. Cela fonctionne -BeginInvoke
mettrons à jour la collection de manière asynchrone. Donc, si vous voulez de cette façon alors son amende. Espérons qu'il a aidé.Si je ne me trompe pas, dans WPF 4.5, vous devriez être en mesure de le faire sans aucun problème.
Maintenant pour résoudre ce problème, vous devez utiliser le contexte de synchronisation. Avant de lancer le thread, vous devez stocker le contexte de synchronisation dans le thread de l'interface utilisateur.
Puis de l'utiliser dans votre fil de discussion:
Prendre un coup d'oeil à ce tuto
http://www.codeproject.com/Articles/31971/Understanding-SynchronizationContext-Part-I
Vous pouvez faire ceci:
Pour .NET 4.5+: Vous pouvez suivre la réponse de Daniel. Dans cet exemple, vous donnez la responsabilité de l'éditeur qu'ils ont besoin de l'appeler ou appeler sur le bon thread:
Ou vous pourriez mettre la responsabilité de votre service/viewmodel/et il vous suffit d'activer CollectionSynchronization. De cette façon, si vous passez un appel, vous n'avez pas à vous inquiéter sur le thread qui vous êtes et sur lequel vous effectuez l'appel. La responsabilité n'est pas pour l'Éditeur plus.
(Ce qui peut vous donner un peu de surcharge de performance mais, ce faisant dans un centre de service, il peut vous faire économiser beaucoup d'exceptions et vous donne plus de facilité de maintenance de l'application.)
Plus d'infos: https://msdn.microsoft.com/en-us/library/system.windows.data.bindingoperations.enablecollectionsynchronization(v=vs. 110).aspx
Dans Visual Studio 2015 (Pro) aller à Debug --> Windows --> les Fils facilement de débogage et de voir sur quels sujets vous sont sur.
J'ai eu le même problème une fois résolu le problème avec AsyncObservableCollection (http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/).
J'ai trouvé une solution ici:
https://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/
Il vous suffit de créer une nouvelle classe et de l'utiliser au lieu de ObservableCollection. Il a travaillé pour moi.
Dans mon cas (je remplir
ObservableCollection
avec des tâches asynchrones et n'ont pas accès àApp
exemple) j'utiliseTaskScheduler.FromCurrentSynchronizationContext()
pour le nettoyage de la collection sur reproché:TaskScheduler.FromCurrentSynchronizationContext()
est la plus simple et la plus logique de la solution. Merci!Si vous utilisez le composant BackgroundWorker vous devriez déclencher l'événement dans le même thread de l'UI.
Pour savoir si vous avez deux vues A et B et le code suivant à l'intérieur d'Un déclenche l'événement WakeUpEvent
La WorkerDoWork méthode est exécutée dans un thread qui n'est pas la même que celle de l'INTERFACE utilisateur.
J'ai été faire cette erreur ainsi:
"Ce type de CollectionView ne prend pas en charge les modifications de son SourceCollection à partir d'un thread différent de l'expéditeur au fil"
S'avère que j'avais créé une nouvelle configuration nommé "Version Android", qui était une copie de la "Libération" de la configuration et de l'utilisait que pour créer la nouvelle version du Gestionnaire d'Archives. J'ai changé à la configuration "Release" et tout construit amende. Pas plus d'erreur.
Espère que cela aide quelqu'un.