Привязка 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.<Свойство>);