C# > UI Programming > WPF > MVVM Pattern
WPF MVVM Example: List Binding and Item Selection
This snippet extends the basic MVVM example to demonstrate binding a list of data to a WPF `ListBox` and handling item selection. It showcases how to display a collection of items in the UI and respond to user selection events.
Project Setup
Create a new WPF application project in Visual Studio. This example builds upon the previous example, so you can reuse the same project structure.
Model: Person Class
The Model represents a person with a name and age. This data will be displayed in the ListBox.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
ViewModel: List and Selection Logic
The `PeopleViewModel` holds an `ObservableCollection` of `Person` objects, which is bound to the `ListBox`. `ObservableCollection` automatically notifies the UI when items are added or removed. The `SelectedPerson` property represents the currently selected item in the `ListBox`. The `SelectedPersonDetails` property displays the details of the selected person and is also updated when the selection changes.
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class PeopleViewModel : INotifyPropertyChanged
{
private ObservableCollection<Person> _people;
private Person _selectedPerson;
public PeopleViewModel()
{
_people = new ObservableCollection<Person>
{
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Charlie", Age = 35 }
};
}
public ObservableCollection<Person> People
{
get { return _people; }
set
{
_people = value;
OnPropertyChanged();
}
}
public Person SelectedPerson
{
get { return _selectedPerson; }
set
{
_selectedPerson = value;
OnPropertyChanged();
OnPropertyChanged(nameof(SelectedPersonDetails));
}
}
public string SelectedPersonDetails
{
get
{
if (SelectedPerson != null)
{
return $"Name: {SelectedPerson.Name}, Age: {SelectedPerson.Age}";
}
return "No person selected.";
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
View: XAML Definition
The `ListBox`'s `ItemsSource` property is bound to the `People` property in the ViewModel. The `SelectedItem` property is bound to the `SelectedPerson` property. The `DisplayMemberPath` property specifies which property of the `Person` object to display in the `ListBox` (in this case, the `Name`). The `TextBlock` displays the details of the selected person.
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<ListBox ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson}" Height="200" Margin="10" DisplayMemberPath="Name"/>
<TextBlock Text="{Binding SelectedPersonDetails}" Margin="10"/>
</StackPanel>
</Grid>
</Window>
Code-Behind: Setting the DataContext
The code-behind sets the `DataContext` of the Window to an instance of the `PeopleViewModel`. This is essential for the data binding to work correctly.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new PeopleViewModel();
}
}
Concepts Behind the Snippet
This snippet demonstrates how to bind a collection of data to a UI control using MVVM. `ObservableCollection` is essential for automatically updating the UI when the collection changes. Handling item selection allows you to respond to user interactions and display relevant information based on the selected item.
Real-Life Use Case
Consider a list of products in an e-commerce application. The `ListBox` would display the product names, and when the user selects a product, the details of that product (price, description, etc.) would be displayed in another part of the UI. This example can be extended to handle more complex data and UI interactions.
Best Practices
Interview Tip
Be prepared to explain the difference between `List` and `ObservableCollection` in the context of data binding. Also, understand how item selection is handled in MVVM and how to display details of the selected item. Be ready to discuss the benefits of using collections.
When to Use Them
Use this pattern when you need to display a list of data in the UI and respond to user selection events. It's particularly useful for applications with a large amount of data and complex UI interactions.
Memory Footprint
`ObservableCollection` can potentially increase memory usage compared to a regular `List` because it needs to track changes and notify the UI. However, the benefits of automatic UI updates usually outweigh this consideration. Be mindful of the size of the collection and consider using virtualization if you are displaying a very large number of items.
Alternatives
Alternatives to using `ListBox` include `ListView` and `DataGrid`, which offer more advanced features for displaying data. You can also use custom controls to create a more tailored UI experience. The choice depends on the specific requirements of your application.
Pros
Cons
FAQ
-
What is the difference between `List` and `ObservableCollection`?
The main difference is that `ObservableCollection` implements the `INotifyCollectionChanged` interface, which allows it to notify the UI when the collection changes (e.g., items are added, removed, or replaced). A regular `List` does not provide this notification mechanism, so the UI will not automatically update when the list changes. -
How do I handle item selection in a `DataGrid` using MVVM?
You can bind the `SelectedItem` property of the `DataGrid` to a property in your ViewModel, similar to the `ListBox` example. When the user selects a row in the `DataGrid`, the `SelectedItem` property in the ViewModel will be updated. You can then respond to this change and perform any necessary actions. -
How can I improve performance when displaying a large number of items in a `ListBox` or `DataGrid`?
Consider using UI virtualization, which only renders the visible items in the list. This can significantly improve performance when displaying a large number of items. Also, use efficient data binding techniques and avoid unnecessary UI updates.