バインディングや XAML だけでそれを行う方法は考えられません。WorkOrder クラスまたは Item クラスを変更したくないという仮定の下でプレイしました (変更したい/変更を許可されている場合は、オブジェクト階層の別のレイヤーで行うことができるため)。
UI 側の回避策として、次のようなことができます。
1) 建物のグループ化情報を保持するクラスを追加します
public class BuildingGroup
{
public string Name { get; set; }
public IEnumerable<WorkOrder> Orders { get; set; }
}
2) コンバーターを作成して、作業指示書の現在のコレクションを建物グループのコレクションに変換します
public class GroupingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var workOrders = (IEnumerable<WorkOrder>)value;
return GroupTheseBadBoysByBuilding(workOrders);
}
private IEnumerable GroupTheseBadBoysByBuilding(IEnumerable<WorkOrder> workOrders)
{
var buildingGroups = workOrders.GroupBy(w => w.Building);
foreach (var buildingGroup in buildingGroups)
{
yield return new BuildingGroup
{
Name = buildingGroup.Key,
Orders = buildingGroup,
};
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
3) 建物グループのデータ テンプレートを設定する
<HierarchicalDataTemplate DataType="{x:Type local:BuildingGroup}" ItemsSource="{Binding Orders}" >
<TextBlock Text="{Binding Path=Name}" Margin="5,0" />
</HierarchicalDataTemplate>
4)コンバーターのインスタンスを作成し、ツリービューで使用します
<TreeView ItemsSource="{Binding Path=Orders,Converter={StaticResource testConverter}}" />
このアプローチの唯一の大きな注意点は、INotifyCollectionChanged の処理が失われることです (使用しているかどうかはわかりません!)。