2013-06-11 1 views
2

Je voulais tester quelque chose donc j'ai construit une petite vue & viewmodel avec un bouton et un ListBox. Lorsque je clique sur le bouton, j'exécute RunCommand comme dans le code ci-dessous. Je ne comprends pas pourquoi le Dispatcher ne déclenche pas l'action que je veux exécuter.Dispatcher pas envoi

Voici le code viewmodel:

public class ViewModel 
{ 
    private ObservableCollection<string> _items = new ObservableCollection<string>(); 
    private ICommand _runCommand; 

    public ICommand RunCommand { get { return _runCommand ?? (_runCommand = new ActionCommand(RunCommandAction)); } } 

    private void RunCommandAction() 
    { 
     Task.Factory.StartNew(() => 
     { 
      if (Thread.CurrentThread == EnvironmentData.UIThread) 
       _items.Add("Eldad"); 
      else 
       Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => _items.Add("Eldad"))); 
     }); 
    } 

    public IEnumerable<string> Items 
    { 
     get { return _items; } 
    } 

    public ViewModel() 
    { 
     _items.Add("Shahar"); 
    } 
} 

Toutes les idées seront grandes

Merci

+1

Que voulez-vous dire par ne déclenche pas l'action? RunCommandAction n'est pas appelé du tout? Ajoutez également le xaml où vous avez déclaré le bouton et utilisé la commande. –

+1

Votre action est conçue pour tout faire dans le thread UI. Cela n'a aucun sens, OMI. – Dennis

+0

Pourquoi pensez-vous que votre action ne se déclenche pas? Je soupçonne que votre action est déclenchée, mais vous la testez via une interface utilisateur liée à votre propriété 'Items'. Puisque vous n'implémentez pas 'INotifyPropertyChanged', et que votre propriété' Items' ne renvoie pas le type 'ObservableCollection', votre interface utilisateur ne va pas se mettre à jour. Essayez de changer votre propriété 'Items' pour taper' ObservableCollection' et tester à nouveau. –

Répondre

2

Dispatcher.CurrentDispatcher - Obtient le Dispatcher pour le thread en cours d'exécution et crée une nouvelle Dispatcher si l'un d'eux n'est pas déjà associé au thread.

Étant donné que vous avez utilisé Task.Factory.StartNew, le thread qui exécute ce n'est pas le thread principal. Si vous souhaitez utiliser le Dispatcher pour le thread d'interface utilisateur, vous devez utiliser App.Current.Dispatcher

+0

Ceci n'est pas conforme à la question. Si la propriété 'Items' est liée à n'importe quel contrôle, alors' Dispatcher' du thread non-UI provoquerait une exception. Mais OP dit, que l'action ne tire pas du tout. – Dennis

+0

@Dennis, Le Dispatcher.CurrentDispatcher utilisé par l'OP provient d'un autre thread et si l'exécution du code passe sur la branche else, l'Action ne sera pas exécutée. Si vous vérifiez le DispatcherOperation retourné par BeginInvoke, il doit toujours être en attente. Cela pourrait signifier ce que l'OP appelle "le Dispatcher ne déclenche pas l'action". –

+0

Merci - cela a résolu - j'ai toujours pensé que Dispatcher (comme je l'ai écrit) va toujours à l'interface utilisateur. –