2012-04-03 16 views
0

Also meine App ist im Grunde eine Shell mit einer ContentControl, die ich mit benutzerdefinierten UserControl 's auffüllen je nach der Benutzerauswahl eines Menüs.KeyBinding inkrementieren seine Befehlsaufrufe

Aber jetzt habe ich ein seltsames Verhalten.

Ich hatte die Content Eigenschaft der ContentControl an eine ViewModel-Eigenschaft angeschlossen, die ich bei Bedarf instanziiere. Das funktioniert großartig, aber ich habe zwei Probleme.

  1. Wenn ich eine Option im Menü auswählen erstellt es eine neue Instanz der angegebenen UserControl und stellen Sie die Content Eigenschaft, um die Schale. Das funktioniert, weil ich das Steuerelement sehe und mit ihm interagieren kann, und wenn ich eine andere Option aus dem Menü wähle, zeigt es mir die andere UserControl, aber, wenn ich wieder die vorher gewählte Option wähle, scheint es das gleiche zuvor zu laden Kontrolle (der rechte aber mit dem älteren Eingang, und ich bin ein neues xxxcontrol() zu tun, bevor es als Content Eigenschaft des ContentControl Einstellung.

  2. ich bin ein Showdialog() aufrufen, aus dem Inneren des Custom Controls über Commands (aus dem User-Control-View-Modell rufe ich die View über MVVM Light messaging auf und zeige dann den Dialog an), und das funktioniert. Aber wenn ich versuche, den Dialog zu schließen, zeige ich ihn wieder genauso oft an das Menü

Zum Beispiel, ich beginne mit A-Menü und zeige den Dialog, dann die Schließen-Taste funktioniert, dann gehe ich zu B-Menü und zurück zu A, dann die Schließen-Taste funktioniert beim zweiten Drücken (zwei ShowDialog() werden genannt) und so weiter ...

Ich weiß nicht, welchen Teil des Codes ich einfügen muss, um diesem Beitrag ein wenig mehr Kontext zu geben, aber jede Eingabe wird geschätzt. Ich stecke mit diesem (meinen) Fehler fest.

-Code

Auf der Schale Ansicht:

<ContentControl Grid.Row="2" Content="{Binding CurrentView}" Margin="15,10"/> 

Auf der Schale Ansichtsmodell:

if (action == null || action == SEARCH_ACTION) 
    { 
     ActionsMenuSelected = SEARCH_ACTION; 
     var view = new SearchDocumentView(); 
     CurrentView = view; 
    } 

Auf der Innenansicht (SearchDocumentView):

public SearchDocumentView() 
{ 
    InitializeComponent(); 
    Messenger.Default.Register<NotificationMessage<Entity>>(this, NotificationMessageReceived); 
} 


private void NotificationMessageReceived(NotificationMessage<Entity> msg) 
{ 
    if (msg.Notification == "ViewResult") 
    { 
     var view = new DocumentViewer(ServiceLocator.Current.GetInstance<IDataService>(),msg.Content); 
     view.ShowDialog(); 
    } 
} 

Auf der Innenansicht (SearchDocumentView) XAML:

<ListBox x:Name="SearchResults" ItemsSource="{Binding SearchResults}" SelectedItem="{Binding SelectedSearchResult}"> 
      <ListBox.InputBindings> 
       <KeyBinding 
          Key="Enter" 
          Command="{Binding ViewResult}" /> 
       <KeyBinding 
          Key="Return" 
          Command="{Binding ViewResult}" /> 
      </ListBox.InputBindings> 
      ... 

Auf der Innenansicht (SearchDocumentView) Ansichtsmodell:

private RelayCommand _viewResut; 

     /// <summary> 
     /// Gets the ViewResult. 
     /// </summary> 
     public RelayCommand ViewResult 
     { 
      get 
      { 
       return _viewResut 
        ?? (_viewResut = new RelayCommand(
             () => 
              { 
               MessengerInstance.Send(new NotificationMessage<Entity>((Entity)SelectedSearchResult, "ViewResult")); 
              }, 
             () => ((Entity)SelectedSearchResult!=null)?true:false)); 
      } 
     } 
+0

Fügen Sie den XAML-Code ein, an dem Sie den Inhalt und den Code für die Instanziierung der Benutzersteuerelemente festlegen. Auch das Code-Snippet, in dem Sie ShowDialog() aufrufen. –

+0

@SreedharlalBNaick Just Edited meine Antwort. Vielen Dank. –

Antwort

1

Warum Sie Ihre alten Daten sehe ich jetzt nicht sehen kann - aber ich denke, Sie Verwenden Sie die gleichen (Modell-) Daten für die neu erstellte Ansicht.

Das zweite Problem sollte hier sein:

public SearchDocumentView() 
{ 
    InitializeComponent(); 
    Messenger.Default.Register<NotificationMessage<Entity>>(this, NotificationMessageReceived); 
} 

Für jede neue Ansicht Ihr Register eine Benachrichtigung, dass Ihre Nachricht Feld zeigen, aber ich sehe nicht, wenn Sie diejenigen deregistrieren und wenn Sie nicht die Der Handler speichert das Viewmodel im Speicher und zeigt weiterhin die Nachrichtenfelder an.

Auch wenn ich es falsch verstanden habe (ist das Ihr "controls" -Viewmodell?) Sollte es etwas sehr ähnliches sein, aber Sie können dies leicht finden, indem Sie einen Breakpoint auf die .Show Ihrer Nachricht setzen und den Callstack ansehen Debuggen.

+0

Danke @Carsten, eigentlich hast du recht. Ich habe den IoC-Container verwendet, um das ViewModel aufzulösen und dann dieselbe Instanz zu verwenden. Nun, für das zweite Problem weiß ich nicht genau, wie ich die Ansicht abmelden soll (sehe nicht, wie das Aufheben der Registrierung des Ansichtsmodells helfen könnte), kannst du etwas detaillierter darüber sein, danke. –

+1

Hallo, soweit ich mich erinnern kann (habe keinen Code hier) sollte es eine 'Unregister' Methode auf der 'IMessenger' (?) Schnittstelle geben (also auch auf' Messenger.Default' erwartet den Empfänger (also call es mit 'Messenger.Default.Unregister (this);' aus Ihrer Sicht) - siehe hier: http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta .aspx – Carsten

+0

Anmerkung: Der Blog-Eintrag besagt, dass MVVM-light schwache Referenzen verwendet, so dass die Anzahl der "Nachrichten", die Sie sehen, mit der Zeit abnehmen sollte, genauso wie ein Seitenknoten;) – Carsten