VirtualizingStackPanel + MVVM +複数選択
-
16-09-2019 - |
質問
私が使用するこのポストをhref="https://stackoverflow.com/questions/803216/managing-multiple-selections-with-mvvm"> ListViewItem.IsSelectedを結合することによって
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListView.ItemContainerStyle>
これは、一般的に動作しますが、私は深刻な問題が発生しました。リストビューにパネルとしてVirtualizingStackPanel
を使用することにより、唯一の目に見えるListViewItem
を作成なっています。私はすべての項目を選択するには、「Ctrlキー+ A」を使用している場合、または最初の項目にショートカットの組み合わせなど、「Shiftキー+ Ctrlキー+エンド」を使用することで、すべての項目が選択されますが、非表示項目について、ViewModelには、そのIsSelectedを得ることはありませんtrueに設定します。 ListViewItem
が作成されていない場合は、結合が働くことができないので、それは、論理的である。
誰もが(離れてVirtualizingStackPanel
を使用していないから)同じ問題を経験し、解決策を見つけた?
解決
私は自分の問題を解決しMVVMパターンで選択を処理する別の方法を発見しました。代わりのviewmodelに選択を維持する、選択がリストビュー/リストボックスから取り出され、コマンドにパラメータとして渡されます。すべてのXAMLで行われます:
<ListView
x:Name="_items"
ItemsSource="{Binding Items}" ... />
<Button
Content="Remove Selected"
Command="{Binding RemoveSelectedItemsCommand}"
CommandParameter="{Binding ElementName=_items, Path=SelectedItems}"/>
私のViewModelでます:
private void RemoveSelection(object parameter)
{
IList selection = (IList)parameter;
...
}
他のヒント
私の場合、私は、リストボックスから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
をバイパスします。