5

ここに画像の説明を入力してください

ComboBoxのバインディングに関する更新の問題があります。この問題を説明する簡単な例を作成しました。以下に関連するすべてのコードを貼り付けます。

したがって、上の画像には、SelectedPersonの「SelectedPerson.FullName」プロパティを示すTextBlock(黒)があります。SelectedPersonのFirstNameプロパティとLastNameプロパティは、FullNameの下の2つのTextBoxに表示されます。ComboBoxDisplayMemberPathは'FullName'にバインドされており、コンボボックスにはPersonオブジェクトのリストが含まれています。

'FullName'プロパティは、TextBlock、ComboBox、およびComboBoxドロップダウンリストで同じである必要があります。

ただし、TextBlockでのみ正しく更新されています。comboBoxドロップダウンは、最初に開いたときに更新されるだけで、その後は更新されません。したがって、テキストボックスのFirstNameを編集してドロップダウンをクリックし、さらに編集してドロップダウンをもう一度クリックすると、SelectedPersonに3つの異なる「FullName」値が表示されます。

「SelectedPerson」が変更されたときに通知するために、コードビハインドでINotifyPropertyChangedを使用しています。これは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();
            }
        }
    }
}
4

1 に答える 1

13

Personオブジェクトにも通知システムを実装する必要があります。変更されたと言うSelectedPersonだけでは十分ではありません。カスタムイベントの代わりに、すでに行っているように実装INotifyPropertyChangedしてイベントを発生させるだけで、機能するはずです。PersonMainWindowPropertyChangedChanged

于 2012-06-15T18:40:03.200 に答える