VirtualizingStackPanel + MVVM + 다중 선택
-
16-09-2019 - |
문제
나는 다음과 유사한 선택 패턴을 구현했다. 이 게시물 뷰 모델을 사용하여 isselected 값을 저장하고 바인딩하여 ListViewItem.IsSelected
viewmodel isselected :
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListView.ItemContainerStyle>
일반적으로 작동하지만 심각한 문제가 발생합니다. a를 사용하여 VirtualizingStackPanel
목록의 패널이보기로 보이는 것만 ListViewItem
창조되고 있습니다. "Ctrl+A"를 사용하여 모든 항목을 선택하거나 첫 번째 항목에서 "Shift+Ctrl+End"와 같은 단축 컷 조합을 사용하여 모든 항목이 선택되지만 가시성 항목의 경우 뷰 모델이 Isselect를받지 않습니다. True로 설정하십시오. 그것은 논리적이기 때문입니다 ListViewItem
생성되지 않으며 바인딩은 작동 할 수 없습니다.
누구나 같은 문제를 경험하고 해결책을 찾았습니다 (사용하지 않는 것 외에 VirtualizingStackPanel
)?
해결책
MVVM 패턴에서 선택을 처리하는 또 다른 방법을 찾아 내 문제를 해결했습니다. ViewModel에서 선택을 유지하는 대신 ListView/Listbox에서 선택을 검색하고 명령에 매개 변수로 전달됩니다. 모두 XAML에서 수행 :
<ListView
x:Name="_items"
ItemsSource="{Binding Items}" ... />
<Button
Content="Remove Selected"
Command="{Binding RemoveSelectedItemsCommand}"
CommandParameter="{Binding ElementName=_items, Path=SelectedItems}"/>
내 뷰 모델에서 :
private void RemoveSelection(object parameter)
{
IList selection = (IList)parameter;
...
}
다른 팁
필자의 경우 ListBox에서 ListBoxEx 클래스를 도출하고 선택 변경에 응답하여 항목보기 모델에서 선택 상태를 시행하여 코드를 추가하여이를 해결했습니다.
private readonly List<IListItemViewModelBase> selectedItems = new List<IListItemViewModelBase>();
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
bool isVirtualizing = VirtualizingStackPanel.GetIsVirtualizing(this);
bool isMultiSelect = (SelectionMode != SelectionMode.Single);
if (isVirtualizing && isMultiSelect)
{
var newSelectedItems = SelectedItems.Cast<IListItemViewModelBase>();
foreach (var deselectedItem in this.selectedItems.Except(newSelectedItems))
{
deselectedItem.IsSelected = false;
}
this.selectedItems.Clear();
this.selectedItems.AddRange(newSelectedItems);
foreach (var newlySelectedItem in this.selectedItems)
{
newlySelectedItem.IsSelected = true;
}
}
}
사용하지 않는 것 외에 VirtualizingStackPanel
, 내가 생각할 수있는 유일한 것은 키보드 바로 가기를 캡처하고 특정 범위를 수정하는 방법을 갖는 것입니다. ViewModel
그들의 항목 IsSelected
속성이 설정됩니다 True
(예 : SelectAll()
, SelectFromCurrentToEnd()
). 기본적으로 우회합니다 Binding
~에 ListViewItem
그러한 경우 선택을 제어합니다.