我有一个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集合。

其他提示

我会使用在ItemContainerStyleListBox前项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
}

希望这有助于!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top