I'm having an issue with a XAML DataGrid which binds to a ObservableCollection. I have 3 classes, A,B,C. The idea is that the ObservableCollection for C will be generated by using Linq to query A and B.
Classes
public class A
{
public int Id { get; set; }
public string Name { get; set; }
}
public class B
{
public int Id { get; set; }
public int Age { get; set; }
}
public class C
{
public string Name { get; set; }
public int Age { get; set; }
}
DataContext Class
private ObservableCollection<A> _as;
public ObservableCollection<A> As
{
get => _as;
set { SetProperty(ref _as, value); }
}
private ObservableCollection<B> _bs;
public ObservableCollection<B> Bs
{
get => _bs;
set { SetProperty(ref _as, value); }
}
public ObservableCollection<C> Cs
{
get
{
var query = from x in As
join y in Bs
on x.Id equals y.Id
select new C() { Name = x.Name, Age = y.Age };
return new ObservableCollection<C>(query);
}
}
MyView.xaml
<DataGrid ItemsSource="{Binding Cs}" Grid.Row="1"/>
If I update the ObservableCollection "As" by removing an item, I can see via a breakpoint that ObservableCollection "Cs" is also updated to reflect the change, but the Datagrid on the UI stays the same. Any help of pointers here would be great, thanks
CodePudding user response:
You have to RaiseNotifyPropertyChanged
when As
or Bs
change to trigger the update of the binding to Cs
:
private ObservableCollection<A> _as;
public ObservableCollection<A> As
{
get => _as;
set
{
if (SetProperty(ref _as, value))
RaisePropertyChanged(nameof(Cs));
}
}
private ObservableCollection<B> _bs;
public ObservableCollection<B> Bs
{
get => _bs;
set
{
if (SetProperty(ref _as, value))
RaisePropertyChanged(nameof(Cs));
}
}
public IEnumerable<C> Cs
{
get
{
var query = from x in As
join y in Bs
on x.Id equals y.Id
select new C() { Name = x.Name, Age = y.Age };
return query;
}
}
Also, you want to RaisePropertyChanged
whenever As
's or Bs
's content changes without the whole collection being replaced, i.e.
public ObservableCollection<A> As
{
get => _as;
set
{
if (_as != null)
_as.CollectionChanged -= NotifyCs;
if (SetProperty(ref _as, value))
RaisePropertyChanged(nameof(Cs));
if (_as != null)
_as.CollectionChanged = NotifyCs;
}
}
private void NotifyCs( object sender, CollectionChangedEventArgs args ) => RaisePropertyChanged(nameof(Cs));