Qual è il modo più semplice per gestire l'evento SelectedItem con MVVM?
-
06-07-2019 - |
Domanda
Nel codice seguente, quando l'utente seleziona Cliente nella casella combinata, il nome del cliente viene visualizzato in una casella di testo. Riempo la casella Combox con una proprietà ObservableCollection sul mio ViewModel ma come posso gestire l'evento SelectedItem nel mio ViewModel?
È facile implementarlo con code-behind come mostrato di seguito, ma come posso farlo con il pattern MVVM?
Al momento ho DelegateCommand e AttachedBehaviors nel mio modello MVVM di base che posso usare, ma non riesco a capire come farli sparare quando " casella combinata seleziona un nuovo elemento " ;.
Visualizza:
<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>
Codice dietro:
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);
}
Soluzione
Dovresti essere in grado di associare una proprietà in ViewModel alla proprietà SelectedItem della casella combinata. Se lo imposti come bind bidirezionale, riceverai una notifica quando viene selezionato SelectedItem perché attiverà il metodo set sulla proprietà.
ViewModel:
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>
Altri suggerimenti
Dai un'occhiata a questa applicazione su www.codeproject.com. Qui utilizzo CollectionView per rilevare l'elemento attualmente selezionato
Aggiorna
Utilizzo di CollectionView per rilevare l'elemento attualmente selezionato
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(Customers);
view.CurrentChanged += delegate
{
SelectedCustomer= (Customer)view.CurrentItem;
};
Ricorda di impostare anche IsSynchronizedWithCurrentItem = " True "