2009-04-23 2 views
10

체크 박스 목록으로 표시하고자하는 AvailableItems의 목록이있어서 사용자가 생성 할 항목을 선택하여 저장할 수 있습니다 ItemsToGenerate이라는 다른 목록에 있습니다 (내 목록은 실제로 문자열 목록에 불과합니다).체크 박스 목록을 체크 된 값 목록에 바인딩하는 가장 간단한 방법은 무엇입니까

<ItemsControl ItemsSource="{Binding Path=AvailableItems}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Content="{Binding}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate>  
</ItemsControl> 

하지만 지금은 각 항목이 ItemsToGenerate 목록에 있다는 사실에, 재산을 Checkbox.IsChecked 바인딩해야 해당 체크 박스에 사용 가능한 모든 항목을 표시

은 간단합니다. 나는이 같은 ListContainmentToBoolConverter하게 생각 :

IsChecked="{Binding Path=ItemsToGenerate, 
      Converter={StaticResource ListContainmentToBoolConverter}}" 

을하지만 각 항목의 값을 전달하는 ConverterParameter을 누락 때문이 작동하지 않지만, ConverterParameter는 지원하지 않기 때문에 내가 할 수 없어 제본.

아이디어가 있으십니까?

답변

12

문제점에 대한 해결책을 찾았습니다.

ItemsControlListBox로 변경하고, 기술을 사용하여 내 ItemsToGenerate 컬렉션 상기 selectedItems를 사이의 바인딩을 추가 한이 here을 설명했다. 기본적으로 첨부 된 속성을 사용하여 모든 사용자 지정 컬렉션을 ListBox.SelectedItems에 동기화 할 수 있습니다.

<ListBox ItemsSource="{Binding AvailableItems}" 
     Behaviors:MultiSelectorBehaviours.SynchronizedSelectedItems= 
      "{Binding ItemsToGenerate}" 
     SelectionMode="Multiple" 
     Background="{x:Null}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel />      
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Content="{Binding}" 
         Margin="3" 
         IsChecked="{Binding RelativeSource= 
          {RelativeSource Mode=FindAncestor, 
          AncestorType={x:Type ListBoxItem}}, 
          Path=IsSelected}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ListBox> 

나는 아직도 내가 처음에 체크 박스에 각 ListBoxItem를 변경하는 데이터 템플릿을 추가하고 각 Checkbox.IsCheckedListBoxItem.IsSelected에 결합하여 (체크 박스의리스트를) 원하는대로이를 표시 할 수 있어요.

내 응용 프로그램에서이 패턴이 나에게 이상적인 솔루션이라는 것을 알았습니다. 이제 첨부 된 속성 하나만 지정하면되고 나머지는 데이터 바인딩으로 처리되므로, 추가 코드가 필요 없습니다.

+1

첨부 된 속성의 구현을보고 싶습니다. 불행히도 이것은 ListBox에서 선택 항목을 재사용 할 때만 작동하지만 템플릿 내에서 체크 박스를 사용하여 ItemsControl을 사용한다면 어떻게 될까요? – jpierson

+0

나는 이것을 시도하고 최종 결과는 좀 펑키 한보고 (http://i.imgur.com/ZRyrjfe.png)입니다. 저는 개인적으로 일반 ListBox를 고수 할 것입니다. – Chris

6

나는 정직하게도 문자열과 체크를 나타내는 부울을 모두 포함하는 개체의 목록을 만들 것입니다.

약간의 Linq를 사용하면 개체 목록을 생성하고 문자열 목록을 바인딩하는 대신 itemSource에 바인드 할 수 있습니다.

특히 사용자가 확인란을 선택/선택 취소 할 수있는 경우 실제로 업데이트해야하는 경우 더 간단합니다.

== 업데이트 ==

코멘트에 대답

이 내 걸릴 내가 실제 문제가 될 수 이해 확실하지 않다 때문에 우리가 전체 목록을 제공 (AvailableItems) 및 목록 의 선택 항목 (ItemsToGenerate) : 그런 다음 속성이라는 항목으로 _Items을 노출시켜,과 같이 목록을 결합 할 수

_Items = from item in AvailableItems 
      select new ItemEntry() { 
        Name = item, 
        IsSelected = ItemsToGenerate.contains(item) 
        }).ToList(); 

public class ItemEntry 
{ 
    public string Name { get; set; } 
    public bool IsSelected {get; set; } 
} 

... :

<ItemsControl ItemsSource="{Binding Path=Items}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate>  
</ItemsControl> 

나중에 필요한 경우 IsSelected가 true 인 항목을 선택하여 필요한 항목을 가져올 수 있습니다.

또한 ItemsToGenerate가 커질 수있는 경우에는 값의 HashSet을 만들어 쿼리에 사용하면 필요한 경우 더 빠르게 만들 수 있습니다.

+0

내가 원하지 않는 이유는 내 데이터가 XML에 저장되고 때로는 손으로 편집되기 때문입니다. 따라서 300 개의 항목을 사용할 수 있고 2 개의 항목 만 생성하려는 경우 Item1 Item2를 작성하면됩니다. –

+0

뭔가가 없는지 확인하려면 내 업데이트를 참조하십시오. –

+0

나는 이것에 대해 다른 방법을 생각해 보았다 : 항목 템플릿이 체크 박스를 바인딩하는 ListBox를 사용했다. ListItem.IsSelected에 체크했다. 그렇다면 ItemsSource를 AvailableItem에 바인딩하고 SelectedItem을 ItemsToGenerate에 바인딩하는 문제 일뿐입니다. –

관련 문제