2009-04-17 13 views
11

Ich versuche, den richtigen Weg zu finden, um die Daten aus einem ChildWindow/Popup mit einem MVVM-Muster in Silverlight (3) zu bekommen. Zum Beispiel: Ich habe eine Hauptseite mit einem Dateneingabeformular und ich möchte ein Popup mit einer Liste von Kunden öffnen. Wenn der Benutzer einen Kunden auswählt, möchte ich den ausgewählten Kunden auf die Hauptseite übertragen. Dies ist, was der (Beispiel) Code, den ich im Moment bin mit:Silverlight Kind Windows in MVVM Muster

Startseite

public partial class MainPage : UserControl 
{ 
    public MainPageViewModel ViewModel { get; private set; } 

    public MainPage() 
    { 
     InitializeComponent(); 
     ViewModel = new MainPageViewModel(); 
     DataContext = ViewModel; 
    } 

    private void SearchCustomer_Click(object sender, RoutedEventArgs e) 
    { 
     ViewModel.SearchCustomer(); 
    } 
} 

public class MainPageViewModel: ViewModel 
{ 
    private string customer; 
    public string Customer 
    { 
     get { return customer; } 
     set { customer = value; RaisePropertyChanged("Customer"); } 
    } 

    public void SearchCustomer() 
    { 
     // Called from a view 
     SearchWindow searchWindow = new SearchWindow(); 
     searchWindow.Closed += (sender, e) => 
     { 
      if ((bool)searchWindow.DialogResult) 
      { 
       Customer = searchWindow.ViewModel.SelectedCustomer.ToString(); 
      } 
     }; 
     searchWindow.Show(); 
    } 
} 

Kindern Fenster

public partial class SearchWindow : ChildWindow 
{ 
    public SearchWindowViewModel ViewModel { get; private set; } 

    public SearchWindow() 
    { 
     InitializeComponent(); 
     ViewModel = new SearchWindowViewModel(); 
     DataContext = ViewModel; 
    } 

    private void OKButton_Click(object sender, RoutedEventArgs e) 
    { 
     DialogResult = ViewModel.OkButtonClick(); 
    } 

    private void CancelButton_Click(object sender, RoutedEventArgs e) 
    { 
     DialogResult = ViewModel.CancelButtonClick(); 
    } 
} 

public class SearchWindowViewModel: ViewModel 
{ 
    private Customer selectedCustomer;   
    private ObservableCollection<Customer> customers; 

    public ObservableCollection<Customer> Customers 
    { 
     get { return customers; } 
     set {customers = value; RaisePropertyChanged("Customers"); } 
    } 

    public Customer SelectedCustomer 
    { 
     get { return selectedCustomer; } 
     set { selectedCustomer = value; RaisePropertyChanged("SelectedCustomer"); } 
    } 

    public SearchWindowViewModel() 
    { 
     Customers = new ObservableCollection<Customer>(); 
     ISearchService searchService = new FakeSearchService(); 
     foreach (Customer customer in searchService.FindCustomers("dummy")) 
      Customers.Add(customer); 
    } 

    public bool? OkButtonClick() 
    { 
     if (SelectedCustomer != null) 
      return true; 
     else 
      return null; // show some error message before that 
    } 

    public bool? CancelButtonClick() 
    { 
     return false; 
    } 
} 

Ist dies der richtige Weg oder gibt es alles mehr "einfach"?

Cheers, Rok

Antwort

6

Mehr hier problematisch ist die Verwendung von Ansicht spezifischen Begriffe und Arten in Ihrer VMs. Klicken Sie auf Ereignisse, DialogResults sollte nicht in der Nähe Ihrer ViewModels sein.

In Bezug auf die Frage, ich hatte eine ähnlich Frage dazu hier: Handling Dialogs in WPF with MVVM

Die Antwort, die ich die Verwendung des Vermittler-Muster, dies zu umgehen akzeptiert war. Guck mal. :)

+2

Danke, ich werde einen Blick darauf werfen. Ich habe herausgefunden, dass ich es "komplett" falsch mache, und ich habe meinen Code bereits geändert, um Befehle zu verwenden (Bindung an ICommand) und das Dialogresultat aus der VM zu entfernen. Der nächste Schritt ist, das Mediator-Muster zu betrachten :) – rrejc

+0

Ich stimme zu, Mediator ist der Weg zu gehen. Blogged darüber: http://basaratali.blogspot.com/2010/12/mediator-for-mvvmlight-like-one-by.html – basarat