2012-08-09 2 views
0

Je définis le DataContext pour ma vue dans le constructeur de la vue sur une instance de mon ViewModel, juste la substance standard. Peu de temps après, un événement UPDATE_RECENT_DOCUMENTS_LIST se déclenche à partir de l'aggrégateur d'événements que ma ViewModel intercepte correctement. Une propriété est modifiée et la méthode onPropertyChanged est appelée, mais elle échoue car l'événement PropertyChanged est null.Événement PropertyChanged null après le paramètre DataContext

La très prochaine chose que je fais est une action à l'interface utilisateur qui soulève un CREATE_PROJECT événement et même ViewModel reçoit des événements, sauf que maintenant, l'événement PropertyChanged n'est plus nul et tout fonctionne comme prévu.

Existe-t-il une durée spécifique qui doit s'écouler après la définition de DataContext avant son enregistrement dans l'événement PropertyChanged? Y at-il un événement que je peux attendre pour m'assurer que l'événement PropertyChanged n'est pas nul?

En outre, je n'ai pas rencontré ce problème en utilisant les événements standard .NET, juste après l'intégration de Prism et en utilisant le très pratique EventAggregator.

Je montre mon code derrière la vue et le ViewModel, en omettant le XAML de vue pour la brièveté.

ToolBarView.xaml.cs:

namespace ToolBarModule 
{ 

public partial class ToolBarView : UserControl 
    {       
     public ToolBarView(ToolBarViewModel toolBarViewModel) 
     { 
      InitializeComponent();    
      this.DataContext = toolBarViewModel;         
     }   
    } 
} 

ToolBarViewModel.cs

namespace ToolBarModule 
{ 

public class ToolBarViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    private ToolBarCommands baseCommands; 
    private IEventAggregator eventAggregator; 

    private KickStartEvent kickStartEvent; 
    private SubscriptionToken subscriptionToken; 

    private ObservableCollection<IDocumentReference> recentDocuments = new ObservableCollection<IDocumentReference>(); 

    private ActionCommand newTest; 
    private ActionCommand openTest; 
    private ActionCommand saveTest;   
    private ActionCommand exitApplication; 

    public ToolBarViewModel(){} 

    public ToolBarViewModel(IEventAggregator eventAggregator) 
    { 
     this.eventAggregator = eventAggregator; 
     baseCommands = new ToolBarCommands(eventAggregator); 
     kickStartEvent = eventAggregator.GetEvent<KickStartEvent>(); 
     subscriptionToken = kickStartEvent.Subscribe(kickStartEventHandler, ThreadOption.UIThread, true, toolBarEventHandlerFilter);    
    } 

    public ICommand NewTest 
    { 
     get 
     { 
      if (newTest == null) 
      { 
       newTest = new ActionCommand(baseCommands.NewTestAction); 
      } 
      return newTest; 
     } 
    } 

    public ICommand OpenTest 
    { 
     get 
     { 
      if (openTest == null) 
      { 
       openTest = new ActionCommand(baseCommands.OpenTestAction); 
      } 
      return openTest; 
     } 
    } 

    public ICommand SaveTest 
    { 
     get 
     { 
      if (saveTest == null) 
      { 
       saveTest = new ActionCommand(baseCommands.SaveTestAction); 
      } 
      return saveTest; 
     } 
    } 


    public ICommand ExitApplication 
    { 
     get 
     { 
      if (exitApplication == null) 
      { 
       exitApplication = new ActionCommand(baseCommands.ExitApplicationAction); 
      } 
      return exitApplication; 
     } 
    } 

    public ObservableCollection<IDocumentReference> RecentDocuments 
    { 
     get 
     { 
      return recentDocuments; 
     } 

     set 
     { 
      recentDocuments = value; 
      onPropertyChanged("RecentDocuments"); 
     } 
    } 

    private void onPropertyChanged(string propertyChanged) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this,new PropertyChangedEventArgs(propertyChanged)); 
     } 

    } 

    private void kickStartEventHandler(KickStartEventsArgs e) 
    { 
     switch (e.EventType) 
     { 
      case KickStartEventsArgs.KickStartEventType.CREATE_PROJECT: 
       onPropertyChanged("RecentDocuments"); 
      break;     


      case KickStartEventsArgs.KickStartEventType.UPDATE_RECENT_DOCUMENTS_LIST: 
      RecentDocuments.Clear(); 

      foreach (IDocumentReference recentDocs in e.KickStartTestList) 
      { 
       RecentDocuments.Add(recentDocs); 
      } 
      onPropertyChanged("RecentDocuments"); 
      break; 
     } 
    } 
} 

}

+0

Avez-vous nommé votre UserControl en XAML? – saber

+0

Fournissez le code XAML de votre UserControl. – saber

+0

Vous créez vous-même ToolBarView ou utilisez Resolve ou RegionManager? .... vous devez peut-être attendre que le contrôle ait été chargé dans l'arborescence Visuel ... c'est-à-dire. attendre jusqu'à après l'événement Loaded .... vous pouvez définir le DataContext dans votre événement Loaded si vous aimez –

Répondre

0

Vous devez nommer votre UserControl dans XAML et de l'utiliser dans la liaison. Quelque chose comme code suivant:

<UserControl x:Name="uc" > 
. 
. 
. 
<TextBox Text="{Binding UserName, Mode=TwoWay, ElementName=uc}"/> 

uc est un nom de votre UserControl, et aussi essayer de mettre DataContext lorsque UserControl chargé.

Espérons cette aide.

+0

Mon UserControl n'est pas nommé, mais après l'avoir nommé, l'événement PropertyChanged est toujours null. – estarkey7

+0

Avez-vous défini ElementName de liaisons? – saber

+0

Toutes mes liaisons fonctionnent correctement, c'est juste que l'événement PropertyChanged est nul immédiatement après le chargement de mon contrôle. Ce que j'ai dû faire cela retardait l'envoi de l'événement autour de 500 ms pour donner à l'événement PropertyChanged le temps de se lier, et cela a corrigé le problème. Merci pour vos contributions Saber! – estarkey7

Questions connexes