I have an updating issue with Binding in my ComboBox. I have created a simplified example illustrate this problem. I will paste all the related code below.
So in the image above, I have a TextBlock (in black) that shows the 'SelectedPerson.FullName' property for the SelectedPerson. The FirstName and LastName properties of the SelectedPerson are shown in the 2 TextBoxes below the FullName. The ComboBox DisplayMemberPath is bound to 'FullName' and the combobox contains a list of Person objects.
The 'FullName' property should be the same in the TextBlock, ComboBox, and ComboBox dropdown list.
However, it is ONLY updating correctly in the TextBlock. The comboBox Dropdown just updates the first time it is opened and doesn't update after that. So if I edit the FirstName in the textbox and click the dropdown and then edit it some more and click the dropdown again, we end up with 3 different 'FullName' values being displayed for the SelectedPerson.
I am using INotifyPropertyChanged in my code behind to notify when "SelectedPerson" is changed. This appears to work fine updating the TextBlock, but for some reason, ComboBox isn't updating with the new "FullName".
I have attempted to send a "FullName" notify when I send 'SelectedPerson' notify, but it doesn't make it work either.
Can anybody tell me why the ComboBox isn't updating when I change the FirstName text?
Thanks.
MainWindow.xaml:
<Window x:Class="ComboBoxBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel Margin="50" Width="150">
<TextBlock Margin="0,0,0,10" Height="30" Padding="8" Background="Black" Foreground="White" Text="{Binding SelectedPerson.FullName}"/>
<TextBox Text="{Binding SelectedPerson.FirstName, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Text="{Binding SelectedPerson.LastName, UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox Margin="0,16,0,0"
ItemsSource="{Binding People}"
DisplayMemberPath="FullName"
SelectedItem="{Binding SelectedPerson, UpdateSourceTrigger=PropertyChanged}">
</ComboBox>
</StackPanel>
</Window>
MainWindow.xaml.cs:
using System.Collections.Generic;
using System.ComponentModel;
namespace ComboBoxBinding
{
public partial class MainWindow : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private List<Person> _people = new List<Person>();
public List<Person> People
{
get { return _people; }
}
private Person _selectedPerson;
public Person SelectedPerson
{
get { return _selectedPerson; }
set
{
_selectedPerson = value;
OnPropertyChanged("SelectedPerson");
}
}
public MainWindow()
{
GenerateLaneConfigurations();
InitializeComponent();
}
private void GenerateLaneConfigurations()
{
People.Add(new Person("Elmer", "Fudd"));
People.Add(new Person("Bugs", "Bunny"));
People.Add(new Person("Donald", "Duck"));
foreach (Person person in _people)
{
person.Changed += person_Changed;
}
SelectedPerson = People[0];
}
void person_Changed()
{
OnPropertyChanged("SelectedPerson");
}
}
}
Person.cs:
namespace ComboBoxBinding
{
public class Person
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; OnChanged(); }
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set { _lastName = value; OnChanged(); }
}
public string FullName
{
get { return string.Format("{0} {1}", FirstName, LastName);}
}
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public delegate void ChangedEventHandler();
public event ChangedEventHandler Changed;
protected void OnChanged()
{
if (Changed != null)
{
Changed();
}
}
}
}
You need to implement the notification system in your Person object as well. Saying that the SelectedPerson
changed isn't good enough. Just implement INotifyPropertyChanged
on Person
like you already do on your MainWindow
and raise the PropertyChanged
event instead of your custom Changed
event and it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With