【问题标题】:WPF Delete button in listview mvvmlistview mvvm中的WPF删除按钮
【发布时间】:2012-11-27 12:50:57
【问题描述】:

我在列表视图中有一个用于删除所选项目的按钮。当我单击按钮时,RemoveSubjectCommand 没有触发。如果我将按钮放在列表视图之外,它工作正常。 hopw 这只是因为嵌套项目。我该如何解决这个问题?

<ListView HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
        HorizontalContentAlignment="Stretch" Grid.ColumnSpan="3" Grid.Row="2"
        ItemsSource="{Binding AssignedSubjects}">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Center" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Width="140" Header="Subjects" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Width="auto">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="X" Command="{Binding RemoveSubjectCommand}"  />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

查看模型,

private ICommand removeSubjectCommand;
**
public ICommand RemoveSubjectCommand
{
    get { return removeSubjectCommand ?? (removeSubjectCommand = new RelayCommand(param => this.RemoveSubject(), null)); }
}
**
private void RemoveSubject()
{ ***
}

如果我输入以下代码,它将正常工作。

<ListView.InputBindings>
    <KeyBinding Key="Delete" Command="{Binding RemoveSubjectCommand}" />
</ListView.InputBindings>

【问题讨论】:

  • 嗨。如果没有将参数发送到命令,如何删除该行?
  • @Javidan,为此您可以使用按钮CommandParameter。例如。使用CommandParameter="{Binding}" 将其绑定到您的ListViewItem 的DataContext,即项目本身。然后,在您的 ViewModel 中,您可以定义 DelegateCommand 以接受参数,例如如public DelegateCommand&lt;object&gt; RemoveSubjectCommand{ get; }(注意我添加的&lt;object&gt;,顺便说一下,它可以是任何其他类型,只要一切保持一致)。

标签: c# wpf mvvm


【解决方案1】:

那是因为按钮的DataContext是ListBoxItem DataContext。所以你需要去父ListView DataContext。

这样做的一种方法是给 ListView 一个名称,并与元素名称绑定

<ListView Name="lv" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
        HorizontalContentAlignment="Stretch" Grid.ColumnSpan="3" Grid.Row="2"
        ItemsSource="{Binding AssignedSubjects}">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Center" />
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.View>
        <GridView>
            <GridViewColumn Width="140" Header="Subjects" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Width="auto">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="X" Command="{Binding ElementName=lv,Path=DataContext.RemoveSubjectCommand}"  />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

【讨论】:

  • 我相信你可以使用binding和financestor跳过命名部分。
  • 对,financestor 是另一种方法,但由于它已经存在于答案中,我选择了这个
  • 我不明白,如果没有通过按钮发送命令参数,我们如何知道要从集合中删除哪个项目? ListView 中的 SelectedItem 属性也没有绑定到 ViewModel...
  • 好吧,我假设项目视图模型有 RemoveSubjectCommand 命令,它知道如何从列表中删除自己。
【解决方案2】:

您需要将命令绑定到使用 FindAncestor。否则,它将尝试使用 ListViewItem 的数据上下文而不是 ViewModel 的数据上下文绑定到 RemoveSubjectCommand

试试这个:

<Button Content="X" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListView}, Path=DataContext.RemoveSubjectCommand}"  />

【讨论】:

  • TemplateParent 不会是 ListView,而是 ListViewitem,不是吗?
  • 必须在您的答案中输入DataContext.RemoveSubjectCommand 而不是RemoveSubjectCommand。谢谢和赞成
【解决方案3】:

如果我把按钮放在列表视图之外,它工作正常

因为RemoveSubjectCommand属性是在ListView的数据上下文中定义的,而不是在item的数据上下文中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 2015-11-28
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    相关资源
    最近更新 更多