2013-07-26 3 views
1

내가 WPF 응용 프로그램 (.NET 4.0) 건물입니다을 selectedItem을하고, 나는 다음과 같은 상황이 :리스트 박스의 ItemSource가 바인딩WPF/MVVM 바인딩 확인란 재산

<ListBox 
    ItemsSource="{Binding Path=Items}" 
    SelectedItem="{Binding Path=SelectedItem}"> 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="Height" Value="48"/> 
     </Style> 
    </ListBox.ItemContainerStyle> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <DockPanel> 
       <!-- ... --> 
       <CheckBox> 
        <CheckBox.IsChecked> 
         <!-- Something here that behaves like SelectedItem binding --> 
        </CheckBox.IsChecked> 
       </CheckBox> 
      </DockPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
  • 을 ObservableCollection <>를 참조하십시오. 리스트 박스의
  • selectedItem 그는 뷰 모델의 속성 selectedItem가 결합된다.

그러나 ViewModel.SelectedItem이 업데이트되면 장기 실행 (2-3 초) 비동기 작업 비트가 시작됩니다. 목록 상자에서 다른 항목을 선택하여 비동기 작업의 많은 수를 대기열에 넣기가 너무 쉽습니다. 대신 ViewModel.SelectedItem을 CheckBox (ItemTemplate에 포함됨)에 바인딩하려고합니다.

저는 WPF에 상당히 익숙하지만, Forms에서 이벤트 처리기를 연결하고 이벤트를 트리거 한 항목을 제외하고 프로그래밍 방식으로 속성을 업데이트하는 모든 길고 못생긴 코드를 작성했습니다.

WPF에서는 ValueConverter를 사용하는 방법을 살펴 보았지만 상위 뷰 모델 (ObservableCollection <>)에 바인딩하는 방법을 알아낼 수 없습니다.

비슷한 요구 사항이있는 사람이 있다면 정말 도움이 될 것입니다.

건배!

./Fredrik

+0

는 않을 것 체크 박스를 반복적으로 클릭하여 많은 수의 비동기 작업을 대기열에 묶는 것도 똑같이 간단합니까?당신이 필요로하는 것은 새로운 것이 시작될 때 현재 실행중인 작업을 취소하는 메커니즘입니다. 그리고 선택한 항목이 변경 될 때 바로 작업하는 대신 작업을 지연하는 것을 고려할 수 있습니다. – Clemens

+0

안녕하세요 클레멘스, 응답 해 주셔서 감사합니다! 그렇습니다. 그러나 비동기 작업이 실행되는 동안은 선택된 상태로의 변경을 막기가 너무 어렵지 않아야합니다. 작업이 실행 중일 때 ListBox를 비활성화하여 동일한 작업을 시도했지만 너무 추했습니다. 추가 된 CheckBox의 이점은 ListBox 내의 선택 항목이 작업과 분리되어있어 사용자가 작업이 실행되는 동안 목록 상자를 둘러 볼 수 있다는 점입니다. – Fredrik

+0

목록 상자 외부에있는 모든 확인란 대신 전용 버튼을 사용하여 현재 선택된 항목에서 작업을 시작할 수도 있습니다. 이는 구현이 쉬울뿐만 아니라보다 직관적 인 UI로 이어질 수 있습니다. – Clemens

답변

0

나는 코드 숨김에 체크 된 상태를 처리에 의존하지 않는 솔루션을 파악, 그래서 후대를 위해 그것을 문서화하는거야.

첫 번째 트릭은 함께하고 GroupName 관련된 대신 RadioButton을 사용하는 것입니다. 같은 그룹 내의 라디오 버튼은 주어진 시간에 자동으로 하나만 확인되므로 확인 된 상태를 수동으로 관리 할 때 발생하는 문제를 피할 수 있습니다.

제 트릭 라디오 버튼 DataContextCommandParameter에 결합한다.

<RadioButton 
    Name="rdbSelected" 
    GroupName="itemsRadioGroup" 
    Command="{Binding 
     RelativeSource={RelativeSource AncestorType=UserControl}, 
     Path=DataContext.SelectItemCommand}" 
    CommandParameter="{Binding 
     RelativeSource={RelativeSource Self}, 
     Path=DataContext}"/> 

라디오 버튼이 체크되지 바로 그 때, 모든 클릭에 불을 명령하지만, 우리는 멀리는 할 수 없습니다이 때문에 달리 CheckBox으로 얻을 라디오 버튼을 취소합니다, 그래서 라디오를 더블 클릭 버튼은 SelecedItem 만 확인합니다. SelectedItem 속성은 PropertyChanged 이벤트를 발생

경우,이 명령 핸들러는 사실 새 값을 설정하거나 반복에 있는지 여부를 확인하도록하는 것이 바람직 할 수있다 이전 :

RelayCommand<object> cmd = new RelayCommand<object>(
    (o) => 
    { 
     if (this.SelectedItem != o) 
      this.SelectedItem = o; 
    }); 
0

안녕 당신은 VM의 명령에있는 확인란을 바인딩 할 수 있으며 명령이 확인란을 선택하면/선택 해제 화재 것입니다.

+0

안녕하세요, 귀하의 회신에 감사드립니다! 이제 명령을 내리면 SelectedItem을 프로그래밍 방식으로 설정할 수있게되었지만 ListBox에 여러 항목이 있으며 각 항목마다 CheckBox가 있습니다. SelectionMode Single 동작을 유지하면서 다른 CheckBox의 선택을 취소하려면 어떻게해야합니까? 건배! – Fredrik

+0

ViewModel에서 변경 사항을 확인하고 변경 사항이 UI에 반영됩니다 – ethicallogics

+0

부울 목록이 해당 체크 박스의 ISelected에 바인드 된 것과 같습니다. 모든 체크 박스를 선택하려면 모든 값을 false로 설정하고 선택한 항목을 설정하십시오. 사실을 열거하십시오. VM의 논리를 얼마나 잘 수행했는지에 대한 모든 것. – ethicallogics

0

ListBoxItem의 isselected 속성을 TemplateBinding을 통해 확인란에 바인딩 할 수 있습니다.

+0

안녕 Nakul, 응답 주셔서 감사합니다! 실제로는 ListBox 선택을 선택 상태와 함께 변경하지 않을 것입니다 (최소한 양방향 바인딩의 경우). 여기서 purpouse는 View-Model의 SelectedItem에 ListBox의 어느 항목 (단일 항목)이 선택되었는지를 반영하는 단일 속성을 갖는 것입니다. 건배! – Fredrik