2009-06-18 2 views
10

Im folgenden Code, , wenn der Benutzer den Kunden in der Combobox auswählt, wird der Name des Kunden in einem Textfeld angezeigt. Ich fülle das Combox-Feld mit einer ObservableCollection-Eigenschaft in meinem ViewModel, aber wie handhabe ich das SelectedItem-Ereignis in meinem ViewModel?Was ist der einfachste Weg, SelectedItem-Ereignis mit MVVM zu behandeln?

Es ist einfach, dies mit Code-Behind zu implementieren, wie unten gezeigt, aber Wie mache ich das mit dem MVVM-Muster?

Ich habe derzeit DelegateCommand und AttachedBehaviors in meinem Grunde MVVM Vorlage, die ich verwenden kann, aber ich kann nicht herausfinden, wie sie zu feuern zu erhalten, wenn „Combobox ein neues Element auswählt“.

Ausblick:

<Window.Resources> 
    <DataTemplate x:Key="CustomerTemplate"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding LastName}"/> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

<DockPanel LastChildFill="False" Margin="10"> 
    <ComboBox 
     x:Name="CustomerList" 
     ItemTemplate="{StaticResource CustomerTemplate}" 
     HorizontalAlignment="Left" 
     DockPanel.Dock="Top" 
     Width="200" 
     SelectionChanged="CustomerSelected" 
     ItemsSource="{Binding Customers}"/> 

    <TextBlock x:Name="CurrentlySelectedCustomer"/> 
</DockPanel> 

-Code Behind:

private void CustomerSelected(object sender, System.Windows.Controls.SelectionChangedEventArgs e) 
{ 
    Customer customer = (Customer)CustomerList.SelectedItem; 
    CurrentlySelectedCustomer.Text = String.Format("{0} {1}", customer.FirstName, customer.LastName); 
} 

Antwort

12

Sie sollten in der Lage sein, eine Eigenschaft zu binden, in denen Sie die SelectedItem-Eigenschaft der ComboBox Ansichtsmodell. Wenn Sie dies als Zwei-Wege-Bindung einrichten, werden Sie benachrichtigt, wenn das SelectedItem geändert wird, da es die set-Methode für die Eigenschaft auslöst.

Ansichtsmodell:

public ObservableCollection Customers 
{ 
    get { return _customers; } 
    set 
    { 
     if (_customers != value) 
     { 
      _customers = value; 
      OnPropertyChanged("Customers"); 
     } 
    } 
} 

public Customer SelectedCustomer 
{ 
    get { return _selectedCustomer; } 
    set 
    { 
     if (_selectedCustomer != value) 
     { 
      _selectedCustomer= value; 
      LastName= value.LastName; 
      OnPropertyChanged("SelectedCustomer"); 
     } 
    } 
} 

public Customer LastName 
{ 
    get { return _lastName; } 
    set 
    { 
     if (_lastName!= value) 
     { 
      _lastName= value; 
      OnPropertyChanged("LastName"); 
     } 
    } 
} 

XAML:

<DockPanel LastChildFill="False" Margin="10"> 
    <ComboBox 
     x:Name="CustomerList" 
     ItemTemplate="{StaticResource CustomerTemplate}" 
     HorizontalAlignment="Left" 
     DockPanel.Dock="Top" 
     Width="200" 
     SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}" 
     ItemsSource="{Binding Customers}"/> 

    <TextBlock x:Name="CurrentlySelectedCustomer" 
       Text="{Binding LastName}"/> 
</DockPanel> 
+0

genau was ich suchte, wusste nicht, dass es so einfach war, danke –

+1

Erinnern Sie sich einfach, dass dies eine Abhängigkeit zwischen Ihrer V/VM ... Wenn Sie diesen Code ohne testen die Ansicht wird der CurrentSelectedCustomer nie aktualisieren! Wenn Sie die CollectionView verwenden ... Es funktioniert, auch wenn Ihre Ansicht nicht an die VM binden! – rudigrobler

+3

Im Allgemeinen stimme ich zu, dass ein CollectionView Vorteile bietet (obwohl es einige Vorbehalte gibt, wenn Sie die gleiche Liste an mehrere Selektoren binden wollen), aber ich denke nicht, dass Ihr Kommentar korrekt ist. In meiner Version gibt es keine Abhängigkeit mehr als deins. Wenn ich beispielsweise einen Test schreiben möchte, um zu überprüfen, ob die LastName-Eigenschaft korrekt aktualisiert wird, brauche ich keine Ansicht. Ich kann die SelectedCustomer-Eigenschaft nur über den Testcode festlegen. –

10

Werfen Sie einen Blick auf this Anwendung auf www.codeproject.com. Hier verwende ich die Collection zu erkennen, das aktuell ausgewählte Element

aktualisieren

Collection Mit aktuell ausgewählte Element erkennen

ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(Customers); 
view.CurrentChanged += delegate 
{ 
    SelectedCustomer= (Customer)view.CurrentItem; 
}; 

Denken Sie daran, auch gesetzt IsSynchronizedWithCurrentItem = „True“

+0

+1 für die Notwendigkeit 'IsSynchronizedWithCurrentItem = "True" zu erwähnen'. Nach einer Stunde, warum 'CurrendChanged', um herauszufinden, in meinem Code nie Sie den Tag gerettet haben gefeuert. – HolySamosa

Verwandte Themen