【问题标题】:WPF ListView Multi-Select MVVM w/ minimal code behindWPF ListView Multi-Select MVVM,后面有最少的代码
【发布时间】:2018-05-09 14:05:22
【问题描述】:

我正在尝试在 WPF 中实现一种方法,让用户在一个框中选择多个项目,然后通过按钮单击将这些选定的项目添加到另一个框中。

我正在尝试使用最少的代码来遵守 MVVM。我发现的解决方案显示 DataContext 正在通过我试图避免的 View 代码进行操作。

我认为我的问题是我不知道如何从 xaml 切换 IsSelected,但不确定。

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=">>" />

视图模型

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

【问题讨论】:

  • 你的问题有点不清楚。你的实际问题是什么?您发布的示例标记中只有 ListView。应该如何调用 AddSelectedStates 方法?
  • 点击带有 >> 的按钮。即,用户在左侧列表视图中选择 3 个状态,单击 >> 按钮,然后填充右侧列表视图。我也会添加按钮代码。

标签: c# wpf mvvm


【解决方案1】:

ListView 具有确定选中哪个项目的内部属性,还具有确定多个选中项目的SelectedItems。但是,ListView 的复数 SelectedItems 是不可绑定的。因此,解决方案是将它们作为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 属性。你应该去掉包装,生活会更轻松。

【讨论】:

  • 谢谢您的好先生。您的解决方案有效,我只更改了一件事,即我将 obj 转换为 ILIST,然后从那里调用 Cast 方法并将其分配给 StatesApproved。非常感谢您的帮助,我真的很想知道为什么 SelectedItems 一开始是私有的。
  • SelectedItems 不是私人的。它只是只读的。
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 2022-08-19
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多