【问题标题】:WPF ComboBox Binding not updating properlyWPF ComboBox 绑定未正确更新
【发布时间】:2012-06-18 20:34:56
【问题描述】:

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

所以在上图中,我有一个 TextBlock(黑色),它显示了 SelectedPerson 的“SelectedPerson.FullName”属性。 SelectedPerson 的 FirstName 和 LastName 属性显示在 FullName 下方的 2 个文本框中。 ComboBox DisplayMemberPath 绑定到“FullName”,并且组合框包含一个 Person 对象列表。

TextBlock、ComboBox 和 ComboBox 下拉列表中的“FullName”属性应相同。

但是,它只会在 TextBlock 中正确更新。组合框下拉菜单仅在第一次打开时更新,之后不再更新。因此,如果我在文本框中编辑 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();
            }
        }
    }
}

【问题讨论】:

    标签: c# wpf data-binding binding combobox


    【解决方案1】:

    您还需要在您的 Person 对象中实现通知系统。说 SelectedPerson 改变是不够的。只需在Person 上实现INotifyPropertyChanged,就像您已经在MainWindow 上所做的那样,并引发PropertyChanged 事件而不是您的自定义Changed 事件,它应该可以工作。

    【讨论】:

      猜你喜欢
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多