c# - WPF ListView Multi-Select MVVM,后面有最少的代码
问题描述
我试图在 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
具有确定选择哪个项目的内部属性,并且还必须SelectedItems
确定多个选定项目。但是,这个复数SelectedItems
ofListView
是不可绑定的。因此,解决方案是将它们作为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
属性。你应该去掉包装,生活会更轻松。
推荐阅读
- python - Python中原生/C代码回调的组成
- c# - 如何在 bot builder 框架 4.0 中发送消息和回复
- r - 在闪亮的应用程序中显示 ggplot 时,如何捕获控制台中出现的 ggplot 警告并显示在应用程序中?
- c# - 我如何在声明@model IENumerable 的视图页面上使用@Html.helper
- blockchain - 当密钥也被区块链使用时,如何在 Azure Key Vault 中使用椭圆曲线 SECP256K1 密钥
- excel - 否则如何进行行循环
- c++ - C++20 模板
用户类型导致 GCC 9 中的 T/const T 类型不匹配 - fabricjs - 以编程方式调整大小后的fabricjs2选择错误
- javascript - 我的脚本没有显示真正可见的元素
- spring - 有什么办法可以在 Spring 中停止后续事件监听器的执行?