WPF ListView Multi-Select MVVM с минимальным кодом позади - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь реализовать в WPF способ выбора пользователем нескольких элементов в одном блоке и с помощью нажатия кнопки добавить эти выбранные элементы в другое поле.

Я пытаюсь придерживаться MVVM с минимальным кодом. Решения, которые я нахожу, показывают, что DataContext манипулируют через код View, за которым я стараюсь избегать.

Я думаю, что моя проблема в том, что я не знаю, как переключить IsSelected с xaml, но не уверен.

enter image description here

1012 * XAML *

<ListView
                            ItemsSource="{Binding AvailableStates, Mode=TwoWay}"
                            SelectedItem="{Binding SelectedStates, Mode=TwoWay}"
                            SelectionMode="Multiple"

                            DisplayMemberPath="state"
                            Grid.Row="1" 
                            Margin="5"
                            Grid.Column="1" 
                            Height="125"
                            Name="lvAvailableStates"
                            Grid.RowSpan="6" 
                            ScrollViewer.VerticalScrollBarVisibility="Visible"
                            ScrollViewer.CanContentScroll="True">
                            <ListView.ItemContainerStyle>
                                <Style TargetType="{x:Type ListBoxItem}">
                                    <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
                                </Style>
                            </ListView.ItemContainerStyle>
                        </ListView>

<Button
                        Grid.Row="2"
                        Grid.Column="2"
                        Margin="10"
                            Command="{Binding AddSelectedStatesCommand}"
                        Content=">>" />

ViewModel

 private ObservableCollection<SelectableItemWrapper<states_approved>> _selectedStates;
    public ObservableCollection<SelectableItemWrapper<states_approved>> SelectedStates
    {
        get { return _selectedStates; }
        set
        {

            _selectedStates = value;
            OnPropertyChanged();
        }
    }

    private void AddSelectedStates(object obj)
    {
        var selected = SelectedStates.Where(s => s.IsSelected)
            .Select(s => s.Item)
            .ToList();

        StatesApproved = selected;
    }

public CustomCommand AddSelectedStatesCommand
    {
        get
        {
            return new CustomCommand(AddSelectedStates, CanExecute);
        }
    } 

Выбранный предмет Обертка

public class SelectableItemWrapper<T>
{
    public bool IsSelected { get; set; }
    public T Item { get; set; }
}

1 Ответ

0 голосов
/ 11 мая 2018

ListView имеет внутреннее свойство для определения того, какой элемент выбран, а также SelectedItems для определения нескольких выбранных элементов. Однако это множественное число SelectedItems из ListView не является обязательным. Таким образом, решение состоит в том, чтобы передать их как CommandParameter.

<ListView x:Name="lvAvailableStates"
          ItemsSource="{Binding AvailableStates, Mode=TwoWay}"
          SelectedItem="{Binding SelectedStates, Mode=TwoWay}" => remove this!
          ...

<Button Command="{Binding AddSelectedStatesCommand}"
        CommandParameter="{Binding SelectedItems, Mode=OneWay, ElementName=lvAvailableStates}" => add this!
        ...

В ВМ

private void AddSelectedStates(IEnumerable<SelectableItemWrapper<states_approved>> selectedItems)
{
    StatesApproved = selectedItems
        .Select(s => s.Item) // only retrieve the Item
        .ToList();
}

Как вы можете видеть на этом этапе, вам даже не нужен SelectableItemWrapper для установки / отмены свойства IsSelected для начала. Вы должны просто снять обертку, и жизнь станет проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...