WPF ComboBox绑定未正确更新

时间:2012-06-15 18:33:02

标签: c# wpf data-binding binding combobox

enter image description here

我的ComboBox中有Binding的更新问题。我创建了一个简化的例子来说明这个问题。我将在下面粘贴所有相关代码。

因此,在上图中,我有一个TextBlock(黑色),显示SelectedPerson的'SelectedPerson.FullName'属性。 SelectedPerson的FirstName和LastName属性显示在FullName下面的2个TextBox中。 ComboBox DisplayMemberPath绑定到'FullName',组合框包含Person对象列表。

“FullName”属性在TextBlock,ComboBox和ComboBox下拉列表中应该相同。

但是,它只能在TextBlock中正确更新。 comboBox Dropdown仅在第一次打开时更新,之后不会更新。因此,如果我在文本框中编辑FirstName并单击下拉列表然后再编辑它并再次单击下拉列表,我们最终会为SelectedPerson显示3个不同的“FullName”值。

我在后面的代码中使用INotifyPropertyChanged来通知“SelectedPerson”的更改。这似乎可以很好地更新TextBlock,但由于某种原因,ComboBox没有使用新的“FullName”进行更新。

当我发送'SelectedPerson'通知时,我尝试发送“FullName”通知,但它也没有使它工作。

当我更改FirstName文本时,有人能告诉我为什么ComboBox没有更新吗?

感谢。

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();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:12)

您还需要在Person对象中实现通知系统。说SelectedPerson改变不够好。只需在INotifyPropertyChanged Person上实施MainWindow,就像您已在PropertyChanged上执行Changed并举起{{1}}事件而不是自定义{{1}}事件,它应该有效。