从通过MVVM RelayCommand一个ListBox删除SelectedItems
-
25-09-2019 - |
题
我有一个WPF列表框的项的列表。我想允许用户选择不同的条目并单击删除按钮,以消除从列表中这些项目。
使用MVVM RelayCommand图案,我已经创建了下面的数字签名的命令:
public RelayCommand<IList> RemoveTagsCommand { get; private set; }
在我的视图,我线了我的RemoveTagsCommand这样的:
<DockPanel>
<Button DockPanel.Dock="Right" Command="{Binding RemoveTagsCommand}" CommandParameter="{Binding ElementName=TagList, Path=SelectedItems}">Remove tags</Button>
<ListBox x:Name="TagList" ItemsSource="{Binding Tags}" SelectionMode="Extended">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
<DataTemplate DataType="{x:Type Model:Tag}">
...
</DataTemplate>
</ListBox.Resources>
</ListBox>
</DockPanel>
我的视图模型的构造设定了命令的一个实例:
RemoveTagsCommand = new RelayCommand<IList>(RemoveTags, CanRemoveTags);
当前实施RemoveTags的感觉笨重,用石膏和复制。有没有办法实现这个?
更好的办法 public void RemoveTags(IList toRemove)
{
var collection = toRemove.Cast<Tag>();
List<Tag> copy = new List<Tag>(collection);
foreach (Tag tag in copy)
{
Tags.Remove(tag);
}
}
解决方案
这看起来还算干净给我,虽然你可能使用SelectedItems
能够绑定Mode=OneWayToSource
对你的虚拟机的属性,然后使用从RemoveTags
绑定集合属性。结果我不能完全肯定,但你可能会能够在这种情况下使用强类型的IList集合。
其他提示
我会使用在ItemContainerStyle
的ListBox
前项IsSelected
属性绑定到在模型(未视图模型),e.g的标志:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
然后,你不需要对你传递什么样的参数在你的指挥担忧。此外,根据我的经验,当它的简单的在一个视图模型的目的在于知道用户选择了它,你会发现其他用途的信息。
该命令中的代码将是这样的:
foreach (Tag t in Tags.Where(x => x.IsSelected).ToList())
{
Tags.Remove(t);
}
你为什么不指定RelayCommand
的类型参数是一个List<Tag>
,因为这是你会得到什么呢?有没有点指定一个更通用的类型相比,由于执行的处理程序是硬编码到工作与Tag
对象的列表。既然你已经做的依赖那里,你还不如让它的类型参数,也是如此。然后你执行的处理程序将不再需要任何转换或复制。
1。)绑定的删除按钮命令在你的视图模型。
2)。当您设置结合,使用由CommandParameter给你的列表框的名称和使用的ElementName = NameOfListBox,路径= SelectedItems采取从列表框中Selecteditems
3。)请确保您的命令在您的视图模型沿参数传递。你会得到一个对象,你可以投作为一个IList。
下面是一个简单的例子,这将有助于你建立你的结构。
在检视:
<Button Command="{Binding CommandInViewModelForRemove}"
CommandParameter="{Binding ElementName=blah,Path=SelectedItems}"
<ListBox x:Name="blah" .... />
在视图模型:
public ViewModel(){
RemoveCommand = new RelayCommand<object>(Remove, CanRemove);
}
private void Remove(object selectedItems){
var list = (IList)selectedItems;
//do some work, cast to view models that represent list items, etc
}
希望这有助于!