Reputation: 137
I would like to add, I have searched on Google, and SO for an answer to this before I posted, but none of the solutions seemed to work for me.
I am trying to select a "Person" from a WPF listbox, and have a property on my viewmodel updated to the selected "Person". It works fine the very first time I select an item. After the first selection, changing to another item does not update the viewmodel "Person".
The ViewModel:
public class PersonViewModel : BaseViewModel
{
private Person _selectedPerson;
private ICommand _addToPeopleCommand;
private ICommand _removeFromPeopleCommand;
public Person NewPerson { get; set; }
public Person SelectedPerson
{
get { return _selectedPerson; }
set
{
_selectedPerson = value;
OnPropertyChanged(nameof(SelectedPerson));
}
}
public ObservableCollection<Person> PeopleList { get; set; }
public ICommand AddToPeopleList
{
get
{
if (_addToPeopleCommand == null)
{
_addToPeopleCommand = new RelayCommand(
p => true,
p => this.PeopleList.Add(this.NewPerson));
}
return _addToPeopleCommand;
}
}
public ICommand RemoveFromPeopleList
{
get
{
if (_removeFromPeopleCommand == null)
{
_removeFromPeopleCommand = new RelayCommand(
p => true,
p => this.PeopleList.Remove(SelectedPerson));
}
return _removeFromPeopleCommand;
}
}
public PersonViewModel()
{
this.NewPerson = new Person();
this.PeopleList = new ObservableCollection<Person>();
}
}
BaseViewModel implements INotifyPropertyChanged. In case anyone is wondering.
And the XAML:
<Window x:Class="MVVM_Test.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:viewModels="clr-namespace:MVVM_Test"
d:DataContext="{d:DesignInstance viewModels:PersonViewModel}"
mc:Ignorable="d"
Title="MainWindow" Height="397" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding NewPerson.FirstName}"
Width="200"
Grid.Row="0"/>
<TextBox Text="{Binding NewPerson.LastName}"
Width="200"
Grid.Row="1"/>
<TextBox Text="{Binding NewPerson.FullName}"
Width="200"
Grid.Row="2"
IsReadOnly="True"/>
<Button Grid.Row="3"
Content="Add"
Margin="50,10,151,10"
Command="{Binding AddToPeopleList}"/>
<ListBox x:Name="listBox"
Margin="10,11,-206,-257"
ItemsSource="{Binding PeopleList}"
SelectedItem="{Binding SelectedPerson, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="4">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding FullName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="remove" Content="Remove"
HorizontalAlignment="Left"
Margin="155,10,0,0"
Grid.Row="3"
VerticalAlignment="Top"
Width="75"
RenderTransformOrigin="0.067,0.9"
Command="{Binding RemoveFromPeopleList}"
CommandParameter="{Binding ElementName=listBox, Path=SelectedPerson}"/>
<TextBlock x:Name="textBlock"
HorizontalAlignment="Left"
Margin="311,15,-206,0"
TextWrapping="Wrap"
Text="{Binding SelectedPerson.FullName}"
VerticalAlignment="Top"
Width="196"
Height="75"
Grid.RowSpan="4"/>
</Grid>
The end goal is to select a person from the listbox and have it removed from the ObservableCollection. I can remove people from the box up until there is only one person left, at which point it stops working. However, as mentioned above, when I select a different person, after having removed one from the list, it no longer will select anyone to remove. Nor will selecting a second person call the setter a second time. I even tested it by including the TextBlock and binding it to the selected person property. It only updates once, the first time.
Upvotes: 2
Views: 510
Reputation: 11977
Your AddToPeopleList command adds the same Person instance again and again. Changing the method to add a copy of NewPerson to the list may fix your problem.
Upvotes: 2