Ho letto attentamente la tua risposta e adesso sono in confusione. Ho ancora difficoltà ad approcciarmi con il Binding della TreeView.
Questo è il mio Model Location
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Markup;
namespace WpfTreeViewMVVM
{
public class Location : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Int32 _ID;
private string _Name;
private Int32 _ParentID;
private ObservableCollection<Location> _Children;
public Int32 ID
{
get { return _ID; }
set
{
_ID = value;
this.OnPropertyChanged("ID");
}
}
public string Name
{
get { return _Name; }
set
{
_Name = value;
this.OnPropertyChanged("Name");
}
}
public Int32 ParentID
{
get { return _ParentID; }
set
{
_ParentID = value;
this.OnPropertyChanged("ParentID");
}
}
public ObservableCollection<Location> Children
{
get { return _Children; }
set { _Children = value; }
}
#region Internals
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
La classe provider che mi fornisce un ObservableCollection<Location>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using WpfTreeViewMVVM.Properties;
namespace WpfTreeViewMVVM
{
public static class DataGenerator
{
public static ObservableCollection<Location> Locations()
{
ObservableCollection<Location> _locations = new ObservableCollection<Location>();
using (Model1Container _dc = new Model1Container())
{
var _root = from rec in _dc.Names
where rec.ParentID == null
select rec;
if (_root.Count() > 0)
{
foreach (Names _n in _root)
{
Location _new = new Location();
_new.ID = _n.ID;
_new.Name = _n.Name;
_new.Children = GetChildren(_new);
_locations.Add(_new);
}
}
}
return _locations;
}
public static ObservableCollection<Location> GetChildren(Location par_LocationParent)
{
ObservableCollection<Location> _locationResult = new ObservableCollection<Location>();
using (Model1Container _dc = new Model1Container())
{
var _children = from rec in _dc.Names
where rec.ParentID == par_LocationParent.ID
select rec;
if (_children.Count() > 0)
{
foreach (Names _n in _children)
{
Location _new = new Location();
_new.ID = _n.ID;
_new.Name = _n.Name;
_new.Children = GetChildren(_new);
_locationResult.Add(_new);
}
}
}
return _locationResult;
}
}
}
Questo è il ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Input;
using System.Collections.ObjectModel;
namespace WpfTreeViewMVVM
{
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<Location> _Locations;
public MainViewModel()
{
// Set Sample Tree Data
Locations = DataGenerator.Locations();
}
public ObservableCollection<Location> Locations
{
get { return _Locations; }
private set
{
if (_Locations == value)
{
return;
}
_Locations = value;
this.NotifyPropertyChanged("Locations");
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
Infine lo XAML
<Window x:Class="WpfTreeViewMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TreeView ItemsSource="{Binding Locations}" Width="300" Height="300">
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView>
</StackPanel>
</Window> L'effetto è che appare la treeview vuota con una riga
con scritto System.Windows.HierarchicalDataTemplate ho l'impressione (oltre a sentirmi idiota) di omettere qualcosa di basilare.
Che dici?