2014-01-20 1 views
1

SHAPES의 계층 구조를 표시하려는 TreeView가있는 간단한 응용 프로그램이 있습니다. MVVM을 사용하고 있으므로 ObservableCollection Shapes의 속성을 가진 ViewModel을 가지고 있습니다.WPF TreeView - VM의 FLAT LIST에서 TreeViewItem 소스 필터링

ShapeVm은 기본 클래스이며 여러 Shape 하위 유형 (SquareVm, CircleVm, ArcVm 등)이 있습니다. 아주 기본적인 것들. ShapeVm 기본 클래스에는 ShapeType (enum : enum {Square, Circle, Arc})이라는 초과 속성이 있습니다. 각 ShapeVm 하위 클래스는 Shape 유형을 제공합니다.

자, 이제 어디로 가는지 확인할 수 있습니다. TreeView, 내가 필요로하는 것은 ShapeType 노드와 그 유형의 도형이 포함 된 각 노드의 계층 적 표시입니다.

그래서 XAML에서는 CollectionViewSource와 같은 다양한 기능을 제공하려고했습니다. ShapeType별로 그룹화하는 방법으로 작동하지만 목록에 존재하는 항목과 그룹 만 표시

TreeView에서 필요한 것은 Group 노드가 표시되는지 여부입니다. 또는 아닙니다.

때문에, 예를 들어, 내가 속성을 노출 곳

이제
<TreeView> 

<!-- Itemtemplate omitted here --> 

    <TreeViewItem Header="Rectangles" IsExpanded="true" ItemsSource="{Binding Shapes}"> 
    </TreeViewItem> 

    <TreeViewItem Header="Squares" IsExpanded="true" ItemsSource="{Binding Shapes}"> 
    </TreeViewItem> 

    <TreeViewItem Header="Circles" IsExpanded="true" ItemsSource="{Binding Shapes}"> 
    </TreeViewItem> 

</TreeView> 

, 내 뷰 모델로 바이올린을했다 (윈도우 모양 '속성'의 DataContext이가있는 ShapesViewModel에 바인딩 ')는 각 셰이프 종류의 기본 셰이프 컬렉션에서 해당 데이터를 가져 오는 컬렉션입니다. ViewModels의 작업이 View가 작업을 수행하는 데 필요한 것이면 View를 '제공'하기로되어 있다는 것을 알고 있습니다. 하지만 나는 Collection Collection 유형을 모두 갖고 싶지는 않습니다. 각 컬렉션 유형은 변경 될 때마다 기본 Shapes 컬렉션과 어떻게 든 동기화되어야합니다. 복잡해집니다.

XAML 내에서 "이봐, '사각형'노드는 Shapes 컬렉션에서 '사각형'만 표시하면됩니다."라는 메시지가 표시됩니다.

감사합니다.

답변

0

XAML에서 각 하위 섹션의 유형을 제한 할 수는 없지만 한 가지 해결 방법은 Shapes 열거 형의 외부 LINQ 조인에서 데이터를 가져 오는 것입니다.

아래 클래스에는 ShapeTypes가있는 Shapes 및 열거 형이 있으며 ShapesData 속성은 아래 xaml을 사용하여 시각화 된 LINQ 외부 조인을 노출합니다.

이 솔루션은 필요에 따라 해당 ShapeType을 가진 항목이없고 TreeView 솔루션에 쉽게 적용될 수있는 빈 그룹을 제공합니다.

public class FixedTypes 
    { 
     public enum ShapeType 
     { 
      Circle, 
      Ellipse, 
      Rectangle 
     } 

     public class Shape 
     { 
      public ShapeType ShapeType { get; set; } 
     } 

     public ObservableCollection<Shape> Shapes { get; set; } 

     public FixedTypes() 
     { 
      this.Shapes = 
       new ObservableCollection<Shape>(
        new[] 
         { 
          new Shape() { ShapeType = ShapeType.Circle }, new Shape() { ShapeType = ShapeType.Ellipse }, 
          new Shape() { ShapeType = ShapeType.Ellipse } 
         }); 
     } 

     public IEnumerable ShapesData 
     { 
      get 
      { 
       var data = from e in (ShapeType[])Enum.GetValues(typeof(ShapeType)) 
          join s in Shapes on e equals s.ShapeType into es 
          from s in es.DefaultIfEmpty() 
          select new { ShapeType = e, Shape = s}; 
       return data; 
      } 
     } 
    } 

XAML은

<Grid> 
     <Grid.Resources> 
      <CollectionViewSource x:Key="fixedTypes" 
            Source="{Binding ShapesData}"> 
       <CollectionViewSource.GroupDescriptions> 
        <PropertyGroupDescription PropertyName="ShapeType" /> 
       </CollectionViewSource.GroupDescriptions> 
      </CollectionViewSource> 
     </Grid.Resources> 

     <ItemsControl ItemsSource="{Binding Source={StaticResource fixedTypes}}"> 
      <ItemsControl.GroupStyle> 
       <GroupStyle> 
        <GroupStyle.ContainerStyle> 
         <Style TargetType="{x:Type GroupItem}"> 
          <Setter Property="Template"> 
           <Setter.Value> 
            <ControlTemplate TargetType="{x:Type GroupItem}"> 
             <GroupBox Header="{Binding Name}"> 
              <ItemsPresenter /> 
             </GroupBox> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </GroupStyle.ContainerStyle> 
       </GroupStyle> 
      </ItemsControl.GroupStyle> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Shape.ShapeType}" /> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </Grid> 
+0

마크 - 덕분에 약속 같은데 ... 한번 풀어주고 어떻게 볼 것입니다. 계속 지켜봐주십시오 :-) – csharper