Frage

Ich habe ein Auswahlmuster ähnlich den in diesen Beitrag mit ein Ansichtsmodell des IsSelected Wert zu speichern, und durch die ListViewItem.IsSelected auf das Ansichtsmodell IsSelected Bindung:

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
    </Style>
</ListView.ItemContainerStyle>

Es funktioniert im Allgemeinen, aber ich begegne ein ernstes Problem. Durch die Verwendung der eine VirtualizingStackPanel wie die Platte in der Listenansicht nur die sichtbare ListViewItem erstellt zu werden. Wenn ich „Strg + A“ verwenden, um alle Elemente auszuwählen, oder durch Tastenkombination solche „Shift + Strg + Ende“ auf den ersten Punkt verwenden, erhalten alle Elemente ausgewählt, aber für die nicht sichtbaren Elemente, wird das Ansichtsmodell nicht bekommen seine IsSelected auf true gesetzt. Das ist logisch, denn wenn die ListViewItem nicht erstellt werden, kann die Bindung nicht.

Jeder erlebt das gleiche Problem und fand eine Lösung (abgesehen von nicht VirtualizingStackPanel verwenden)?

War es hilfreich?

Lösung

fand ich eine andere Art und Weise Auswahl der MVVM Muster der Handhabung, die mein Problem gelöst. Anstatt die Auswahl im Ansichtsmodell beibehalten wird, wird die Auswahl aus dem Listview / List-Box abgerufen und als Parameter an den Befehl übergeben. Alles in XAML getan:

<ListView 
    x:Name="_items"
    ItemsSource="{Binding Items}" ... />

<Button 
    Content="Remove Selected" 
    Command="{Binding RemoveSelectedItemsCommand}" 
    CommandParameter="{Binding ElementName=_items, Path=SelectedItems}"/>

in meinem Ansichtsmodell:

private void RemoveSelection(object parameter)
{
    IList selection = (IList)parameter;
    ...
}

Andere Tipps

In meinem Fall landete ich diese Lösung durch eine ListBoxEx Klasse von ListBox ableiten, und das Hinzufügen von Code Auswahl Änderungen zu reagieren, den Auswahlzustand auf den Punkt Ansicht Modelle Durchsetzung:

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;
        }
    }
}

Neben nicht VirtualizingStackPanel verwenden, das einzige, was ich denken kann, ist diese Tastenkombinationen zu erfassen und haben Methoden für einen bestimmten Bereich Ihrer ViewModel Artikel zu modifizieren, so dass ihre IsSelected Eigenschaft auf True (zB SelectAll(), SelectFromCurrentToEnd()) . Im Grunde genommen unter Umgehung des Binding auf ListViewItem für die Auswahl für solche Fälle zu steuern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top