The working solution below
XAML:
<Window.Resources>
<local:AreasConverter x:Key="AreasConverter"/>
</Window.Resources>
<TreeView Name="AreasTreeView" Height="350">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Converter={StaticResource AreasConverter}}">
<TextBlock Text="{Binding Path=ShortName}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
ObservableCollection cs:
class AreasCollection:ObservableCollection<Area>
{
private DBEntities _context;
public DBEntities Context
{
get { return _context; }
}
public AreasCollection(IEnumerable<Area> Areas, DBEntities context)
: base(Areas)
{
_context = context;
foreach (Area a in Areas)
{
a.Areas.AssociationChanged +=new CollectionChangeEventHandler(Areas_AssociationChanged);
}
}
void Areas_AssociationChanged(object sender, CollectionChangeEventArgs e)
{
if (e.Action == CollectionChangeAction.Remove)
{
this.Context.DeleteObject((Area)e.Element);
this.Context.DeleteObject((SpareDevice)e.Element);
this.Context.DeleteObject((AreaDevice)e.Element);
this.Context.DeleteObject((Executor)e.Element);
}
}
protected override void InsertItem(int index, Area item)
{
item.Areas.AssociationChanged += new CollectionChangeEventHandler(Areas_AssociationChanged);
this.Context.AddToAreas(item);
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
Area a = this[index];
a.Areas.AssociationChanged -= Areas_AssociationChanged;
for (int i = a.Areas.Count - 1; i >= 0; i--)
{
this.Context.DeleteObject(a.Areas.ElementAt(i));
}
for (int i = a.SpareDevices.Count - 1; i >= 0; i--)
{
this.Context.DeleteObject(a.SpareDevices.ElementAt(i));
}
for (int i = a.AreaDevices.Count - 1; i >= 0; i--)
{
this.Context.DeleteObject(a.AreaDevices.ElementAt(i));
}
for (int i = a.Executors.Count - 1; i >= 0; i--)
{
this.Context.DeleteObject(a.Executors.ElementAt(i));
}
this.Context.DeleteObject(this[index]);
base.RemoveItem(index);
}
}
Converter Class cs:
public class AreasConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var item = value as Area;
return item.Areas.Where(a => a.ParentArea_ID == item.ID);
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML.cs:
public MainWindow()
{
InitializeComponent();
AreasTreeView.ItemsSource = context.Areas.Where(a => a.ParentArea_ID == null);
}