4

트리 뷰에 계층 구조를 표시해야합니다. 그러나 세부 정보는 데이터 격자에 표시되어야합니다.WPF Treeview 노드에 DataGrid 포함

How I'd like it to be

어떻게 이것을 달성하기 위해 내 템플릿을 작성해야합니까? 나는 지금 템플릿에 대한 이해를 오해하고있다.

<TreeView ItemsSource="{Binding Path=Categories}"> 
     <TreeView.Resources> 
      <HierarchicalDataTemplate DataType="{x:Type stackProjects:Category}" ItemsSource="{Binding Path=SubCategories}"> 
       <TextBlock Margin="3" Text="{Binding Path=CategoryName}"/> 
      </HierarchicalDataTemplate> 

      <HierarchicalDataTemplate DataType="{x:Type stackProjects:SubCategory}" ItemsSource="{Binding Path=Details}"> 
       <TextBlock Text="{Binding Path=SubCategoryName}"/> 
      </HierarchicalDataTemplate> 

      <DataTemplate DataType="{x:Type stackProjects:Detail}" > 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Margin="3" Text="{Binding Path=Name}"/> 
        <TextBlock Margin="3" Text=" - "/> 
        <TextBlock Margin="3" Text="{Binding Path=Info}"/> 
       </StackPanel> 
      </DataTemplate> 
     </TreeView.Resources> 
    </TreeView> 

답변

8

해결 방법을 발견했습니다. 세부 정보는 IEnumerable 속성을 가진 단일 요소 내에서 컬렉션으로 제공되어야한다는 것을 이해해야했습니다. 최선의 해결책은 아니지만 효과가있을 수 있습니다.

내 컬렉션을 하나의 하나로 랩핑하기 위해 변환기를 만들어야했습니다. 래퍼

public class BoxingItemsConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var values = value as IEnumerable; 
     var type = parameter as Type; 

     if (values == null || type == null) 
      return null; 

     if (type.GetInterfaces().Any(x => x == typeof (IItemsWrapper))) 
     { 
      var instance = (IItemsWrapper) type.Assembly.CreateInstance(type.FullName); 
      instance.Items = (IEnumerable) value; 
      //returned value should be IEnumerable with one element. 
      //Otherwise we will not see children nodes 
      return new List<IItemsWrapper> {instance}; 
     } 
     return null; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

예 :

internal interface IItemsWrapper 
{ 
    IEnumerable Items { get; set; } 
} 

public class ItemsWrapper : IItemsWrapper 
{ 
    public IEnumerable Items { get; set; } 
} 

public class DetailItemsWrapper : ItemsWrapper{} 

public class InvoiceItemsWrapper:ItemsWrapper{} 

그리고 XAML. 그것은 많은 변화를 요구하지 않을 것입니다. 복싱 변환기를 사용하고 변환기 매개 변수로 반환 할 형식을 설정하면됩니다.

<TreeView ItemsSource="{Binding Path=Categories}"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type wpfProj:Category}" ItemsSource="{Binding Path=SubCategories}"> 
      <TextBlock Margin="4" Text="{Binding Path=CategoryName}"/> 
     </HierarchicalDataTemplate> 

     <HierarchicalDataTemplate DataType="{x:Type wpfProj:SubCategory}" 
            ItemsSource="{Binding Path=Details, Converter={StaticResource boxingItems}, ConverterParameter={x:Type wpfProj:DetailItemsWrapper}}" > 
      <StackPanel> 
       <TextBlock Margin="4" Text="{Binding Path=SubCategoryName}"/> 
      </StackPanel> 
     </HierarchicalDataTemplate> 

     <DataTemplate DataType="{x:Type wpfProj:DetailItemsWrapper}" > 
      <DataGrid ItemsSource="{Binding Path=Items}"/> 
     </DataTemplate> 
    </TreeView.Resources> 
</TreeView> 

내가 보관에 sample을 업로드했습니다. 나는이 충분히 감사 할 수

DataGrid for TreeView nodes

+0

: 여기 처럼 보이게 않는 방법이다. – user575219

+0

@ user575219 도움이 된 것을 기쁘게 생각합니다. – Artiom