Я пытаюсь изучить WPF с C#, так что терпите меня, если вопрос наивный.
- У меня есть класс с именем Person с 2 свойствами (FirstName, LastName) и 1 вычисляемым свойством (FullName), который реализует INotifyPropertyChanged.
- У меня есть ObservableCollection типа Person, который я связал с ListBox.
- У меня есть экземпляр Person, названный SelectedPerson, с которым я связан свойство ListBox SelectedItem.
- У меня есть два TextBox, которые связаны со свойствами SelectedPerson.FullName и SelectedPerson.LastName.
Пока что все работает так, как должно:
- Нажатие (выбор) человека из ListBox обновляет экземпляр SelectedPerson, и это, в свою очередь, заполняет текстовые поля правильной информацией
- При изменении содержимого TextBox обновляется экземпляр SelectedPerson, и это в очередь обновляет содержимое ListBox (когда отредактированный TextBox теряет фокус)
* 1 020 * То, чего я хочу достичь сейчас, это как-то прослушивать событие PropertyChanged SelectedPerson, поэтому после изменения содержимого TextBox я могу запустить некоторый код. Я хочу, чтобы код запускался один раз, после изменения связанного свойства (например, как обновляется ListBox после остановки редактирования), поэтому я не хочу слушать событие TextBox TextBox.
Могу ли я использовать событие PropertyChanged для SelectedPerson, поэтому независимо от того, какой Person является текущим SelectedItem, я могу прослушивать событие PropertyChanged или мне нужно использовать событие PropertyChanged для каждого экземпляра Person в ObservableCollection? (или ... что-то другое?)
Для справки, здесь приведены соответствующие выдержки из кода для всего вышеперечисленного
Класс Person
public class Person : INotifyPropertyChanged
{
...
public string FirstName
{
get { return _firstName; }
set { _firstName = value; OnPropertyChanged("FirstName"); OnPropertyChanged("FullName"); }
}
public string LastName
{
get { return _lastName; }
set { _lastName = value; OnPropertyChanged("LastName"); OnPropertyChanged("FullName"); }
}
public string FullName { get { return $"{LastName} {FirstName}"; } }
}
MainWindow
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<Person> People { get; set; }
private Person _selectedPerson;
public Person SelectedPerson
{
get { return _selectedPerson; }
set { _selectedPerson = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedPerson")); }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
People = new ObservableCollection<Person>
{
new Person { FirstName = "John", LastName = "Doe" },
new Person { FirstName = "Jane", LastName = "Smith" }
};
}
}
И элементы XAML
...
<ListBox Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Path=People}" SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" DisplayMemberPath="FullName" Margin="10"/>
<StackPanel Grid.Row="1" Grid.Column="2" Orientation="Vertical" Margin="10" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Text="First Name" HorizontalAlignment="Right" Margin="10"/>
<TextBox Text="{Binding SelectedPerson.FirstName, Mode=TwoWay}" Width="120" Margin="10"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Last Name" HorizontalAlignment="Right" Margin="10"/>
<TextBox Text="{Binding SelectedPerson.LastName, Mode=TwoWay}" Width="120" Margin="10"/>
</StackPanel>
</StackPanel>
...