I'm building a WPF software to manage a stock of electronics components.
I have the following structure:
public class Part
{
public string Manufacturer { get; set; }
public string PartNumber { get; set; }
}
public class Resistor : Part
{
public string Resistance { get; set;}
public string Power { get; set;}
}
public class Capacitor : Part
{
public string Capacitance { get; set; }
public string Voltage { get; set; }
}
Resistor and Capacitor are subtypes of Part.
I'm binding a DataGrid
to an ObservableCollection<Part>
, and using a ListCollectionView
to add filtering and grouping functionality.
What I'm trying to accomplish is when I filter the ListCollectionView
to get only the Resistor
subtype, I want the DataGrid
to update it's columns to show the properties of Resistor
type and it's base class Part
(so I would get the columns Manufacturer, PartNumber, Resistance and Power). At the same time, if I filter the ListCollectionView
to get Capacitor
subtype, the DataGrid
should have the Capacitor
class public properties and the Part
public properties (Manufacturer, PartNumber, Capacitance and Voltage).
Finally, If there's no filtering applied, the DataGrid
would show only Part
properties (Manufacturer and PartNumber).
I tried to use the AutoGenerateColumns=true
but the DataGrid
only shows Part
properties, even if I filter the ListCollectionView
to have only Resistors
. I also tried to change the type of the ObservableCollection
to dynamic
and it didn't work either.
How can I change the DataGrid
columns based on type of the object contained in the ObservableCollection
?
Here is the solution using autogenerate. Simply implement the ITypedList interface on the observable collection...
public class Parts : ObservableCollection<Part>, ITypedList
{
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
if(Count == 0)
{
return TypeDescriptor.GetProperties(typeof(Part));
}
else
{
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this[0]);
return pdc;
}
}
public string GetListName(PropertyDescriptor[] listAccessors)
{
return "Parts";
}
}