2012-05-30 3 views
2

ItemsControl에 표시하려는 항목 모음이 있습니다. 그런 다음 각 항목에는 각 항목 안에 가로로 표시해야하는 하위 항목 모음이 있습니다. 내 질문은 어떻게 내가 XAML에서 하위 항목을 정렬합니까? 나는 일반적으로 CollectionViewSource를 사용하지만이 경우에는 작동하지 않습니다. 다음은 간단한 예제입니다. 이 경우 somedata는 항목 모음 (문자열)이고 항목은 chars 모음입니다. 이 예제를 수정하여 각 행에 모든 문자가 정렬되도록하고 싶습니다. 당신은 내부 ItemsControl에에 값 컨버터를 사용할 수WPF 하위 컬렉션 정렬

<ItemsControl Name="mainList"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <ItemsControl ItemsSource="{Binding}" > 
       <ItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
         <StackPanel Orientation="Horizontal"></StackPanel> 
        </ItemsPanelTemplate> 
       </ItemsControl.ItemsPanel> 
       <ItemsControl.ItemContainerStyle> 
        <Style TargetType="ContentPresenter"> 
         <Setter Property="Margin" Value="0,0,5,0"></Setter> 
        </Style> 
       </ItemsControl.ItemContainerStyle> 
      </ItemsControl> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

답변

1

합니다. 코드에서

<ListBox ItemsSource="{Binding}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <StackPanel.Resources> 
        <CollectionViewSource Source="{Binding SubItems}" x:Key="subItemsViewSource"> 
         <CollectionViewSource.SortDescriptions> 
          <scm:SortDescription Direction="Ascending" /> 
         </CollectionViewSource.SortDescriptions> 
        </CollectionViewSource> 
       </StackPanel.Resources> 
       <TextBlock Text="{Binding Name}" /> 
       <ListBox ItemsSource="{Binding Source={StaticResource subItemsViewSource}}"> 
        <ListBox.ItemsPanel> 
         <ItemsPanelTemplate> 
          <StackPanel Orientation="Horizontal"></StackPanel> 
         </ItemsPanelTemplate> 
        </ListBox.ItemsPanel> 
       </ListBox> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox>  

뒤에 일부 데이터와 데이터 컨텍스트를 초기화 :

public class Item : ViewModel 
{ 
    public String Name 
    { 
     get { return name; } 
     set 
     { 
      if (name != value) 
      { 
       name = value; 
       OnPropertyChanged("Name"); 
      } 
     } 
    } 
    private String name; 

    public ObservableCollection<String> SubItems 
    { 
     get 
     { 
      return subItems ?? (subItems = new ObservableCollection<String>()); 
     } 
    } 
    private ObservableCollection<String> subItems; 
} 

... 마크 업 : 다음은 샘플보기 모델의

public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = new ObservableCollection<Item> 
     { 
      new Item 
      { 
       Name = "John", 
       SubItems = 
       { 
        "Mary", "Peter", "James" 
       }, 
      }, 
      new Item 
      { 
       Name = "Homer", 
       SubItems = 
       { 
        "Lisa", "Bart", "Marge" 
       }, 
      } 
     }; 
    } 

트릭 자원을 넣어이다 CollectionViewSource를 마스터 목록 항목의 레이아웃 컨트롤의 리소스로 설명합니다.

+0

완벽! 고맙습니다. ItemsSource를 리소스 뒤에 정의하면 CollectionViewSource를 ListBox/ItemsControl의 리소스로 사용할 수 있다는 것을 알았습니다. 이는 ItemsSource에 긴 핸드 구문을 사용하지만 잠재적으로 불필요한 부모 객체를 정의하지 않아도된다는 것을 의미합니다. 게다가 ListBox에 정의 된대로 조금 더 깔끔하게 처리한다고 생각합니다. – MikeKulls

+0

BTW, Marge가 정말로 Homer의 SubItem이되어야합니까? :-)) – MikeKulls

+0

@MikeKulls : ... 당신이 그들의 관계를 좀 더 넓게 본다면 : D : D ... 질문에 대해 : 예, 당신 말이 맞습니다. 요점은 바인딩 엔진이 바인딩을 수행하기 전에 ** 자원을 정의해야한다는 것입니다. 물론 WPF의 다른 많은 경우와 마찬가지로 "이전에"할 수있는 여러 가지 방법이 있으며 마음에 드는 것을 자유롭게 선택할 수 있습니다. – Dennis

0

(창 태그 내부)에 XAML로

 string[] somedata = new string[] { "afkhsdfgjh", "fsdkgjhsdfjh", "sdfjhdfsjh" }; 
     mainList.ItemsSource = somedata; 

그리고이 :

넣고이는 윈도우의 생성자 . 변환기는 정렬 된 배열을 반환합니다.

public class ArraySortConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value != null && value is string) 
     { 
      return new string((value as string).OrderBy(ch => ch).ToArray()); 
     } 
     return null; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException("Cannot convert back"); 
    } 
} 

난 당신이 또한 실제로 컨버터, 같은 것을 사용할 수 있도록하기 위해 ItemsControl.ItemTemplate을 추가해야합니다 가정 : 당신은뿐만 아니라 하위 항목에 대한 CollectionViewSource를 사용할 수 있습니다

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <ContentPresenter Content="{Binding Converter={StaticResource ArraySorter}}" /> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 
+0

답장을 보내 주셔서 감사합니다. 나는 당신이 이미 정렬하려고하는 데이터를 취하고 유형에 기반하여 그것을 정렬하는 방법에 대한 결정을 내리는 이와 같은 변환기를 이미 가지고 있다고 언급 했어야한다. 예를 들어 IEnumerable 직원을 전달하면 LastName, FirstName으로 정렬해야합니다. 순수한 XAML 구현이있을 것이라고 생각했습니다. 우리가 변환기를 가져 와서 SortDescriptions 콜렉션을 얻었다면 collectionViewSource와 거의 같을 것이라고 생각합니다. BTW, 대답의 두 번째 부분은 필요하지 않습니다, 변환기는 기존의 바인딩에 추가 할 수 – MikeKulls