Привязка ListBox к ComboBox MVVM WPF c#

У меня имеятся следующий View:

<Window x:Class="WpfApp1.ManagerWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ClassLibrary1;assembly=ClassLibrary1" 
        d:DataContext="{d:DesignInstance Type=local:DailyReportsModelView}"
        mc:Ignorable="d"
        Title="ManagerWindow" Height="450" Width="800">
    <Grid>
        <TabControl>
            <TabItem Header="Отчёты">
                <Grid Background="#FFE5E5E5">
                    <ListBox ItemsSource="{Binding Reports}" SelectedItem ="{Binding SelectedReport}" Margin="0,0,397,0">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Margin="5">
                                    <TextBlock Text="{Binding Path=Locksmith}" />
                                    <TextBlock Text="{Binding Path=Date}" />
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>

                    <StackPanel Grid.Column ="1" Background="#FFE5E5E5" DataContext ="{Binding SelectedReport}" Margin="397,0,0,0">
                        <TextBlock Text="Выбранный элемент"  />
                        <TextBlock Text="Количество деталей" />
                        <TextBox Text="{Binding DetailsCount, UpdateSourceTrigger=PropertyChanged}"/>
                        <TextBlock Text="Дата" />
                        <TextBox Text="{Binding Date, UpdateSourceTrigger=PropertyChanged}" />
                        <TextBlock Text="Работник" />
                    </StackPanel>
                    <ComboBox ItemsSource="{Binding Locksmiths}" SelectedItem="{Binding SelectedLocksmith}" Margin="402,104,0,258"/>
                </Grid>
            </TabItem>
        </TabControl>

    </Grid>
</Window>

И следующий ViewModel:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public class DailyReportsModelView : INotifyPropertyChanged
    {
        private Report _selectedReport;
        private Locksmith _selectedLocksmith;

        public ObservableCollection<Report> Reports { get; set; }
        public ObservableCollection<Locksmith> Locksmiths { get; set; }
        public Report SelectedReport
        {
            get { return _selectedReport; }
            set
            {
                _selectedLocksmith = value.Locksmith;
                _selectedReport = value;
                OnPropertyChanged("SelectedLocksmith");
                OnPropertyChanged("SelectedReport");
            }
        }

        public Locksmith SelectedLocksmith
        {
            get { return _selectedLocksmith; }
            set
            {
                _selectedLocksmith = value;
                OnPropertyChanged("SelectedLocksmith");
            }
        }

        public DailyReportsModelView(Workshop workshop)
        {
            DAO dao = new DAO();

            Reports = dao.GetReports();
            Locksmiths = dao.GetLocksmiths(workshopId: workshop.Id);
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string prop = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    }
}

При выборе элемента в ListBox, изменения в полях StackPanel с DataContext'ом SelectedReport происходят, однако ComboBox не реагирует на данные изменения, в чём проблема?


Ответы (2 шт):

Автор решения: Дмитрий Иванов

У вас ComboBox биндится на SelectedLocksmith, а при изменении SelectedReport оповещается только изменение SelectedReport. Добавьте OnPropertyChanged("SelectedLocksmith"); в set свойства SelectedReport.

→ Ссылка
Автор решения: aepot

Присваивать поля, не относящиеся к текущему свойству в сеттере не стоит.

public Report SelectedReport
{
    get => _selectedReport;
    set
    {
        _selectedReport = value;
        SelectedLocksmith = value.Locksmith;
        OnPropertyChanged();
    }
}

public Locksmith SelectedLocksmith
{
    get => _selectedLocksmith;
    set
    {
        _selectedLocksmith = value;
        OnPropertyChanged();
    }
}

При этом value.Locksmith должно быть частью коллекции Locksmiths.

Если у вас этот объект отдельно, то нужно выбрать объект из коллекции, например так:

SelectedLocksmith = Locksmiths.FirstOrDefault(x => value.Locksmith.<Свойство> == x.<Свойство>);
→ Ссылка