【问题标题】:Deleting row in listview using Command + CommandParameter in WPF + MVVM使用 WPF + MVVM 中的 Command + CommandParameter 删除列表视图中的行
【发布时间】:2011-10-21 01:06:34
【问题描述】:

我想使用 Command 和 CommandParameter 删除 ListView 控件中的一行,如下所示。

<GridViewColumn Header="X">
<GridViewColumn.CellTemplate>
    <DataTemplate>
        <StackPanel>
           <TextBlock Text="{Binding CriteriaId}"/>
           <Button Name="btnDeleteCriterion" Tag="{Binding CriteriaId}" Content="{Binding CriteriaId}" Foreground="Red" FontWeight="Bold" 
                                                             Command="{Binding DeleteCriterionCommand}" 
                                                                        DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType=ListView}}"
                                                             CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=Tag}"
                                                                        />
        <StackPanel>
    </DataTemplate>
</GridViewColumn.CellTemplate>

我正在尝试获取 Button 的 Tag 属性并将其传递给上面的命令,而不是像这样从列表中删除它。

在 XAML 之上编辑并添加了一个 TextBlock,它使用与 Button 的标记和内容相同的绑定,但不知何故 Button 没有获得值,但 TextBlock 可以!?

    public void DeleteCriterion(object criterionId)
    {
        int crtId = (int)criterionId;
        Criterion crt = _criteria.FirstOrDefault((c) => c.CriterionId == crtId);
        if (crt != null)
            _criteria.Remove(crt);
    }

但我总是将criteriaId 参数设为空。

我做错了什么?

【问题讨论】:

    标签: wpf listview command commandparameter


    【解决方案1】:

    由于您在按钮内显式设置 DataContext,当您执行 {Binding SomeProperty} 之类的绑定时,它将假定 SomeProperty 在您刚刚设置的 DataContext 中。尝试使用更明确的绑定,例如:

    "{Binding RelativeSource={RelativeSource AncestorType=StackPanel}, Path=DataContext.CriteriaId}" 
    

    这将为您提供正确的 DataContext 的 CriteriaID,就像 TextBlock 一样。

    【讨论】:

    • 是的,有效:)。但只是稍微更正"{Binding RelativeSource={RelativeSource AncestorType=StackPanel}, Path=DataContext.CriteriaId}"。谢谢一堆 Jakub。
    • Jakub,我添加了 StackPanel 来容纳 TextBlock。现在我不需要 TextBlock,我也不需要 StackPanel。在这种情况下,如果我在您建议的答案中设置 Path="GridViewColumn" ,它将不起作用。我是否必须保留 StackPanel 才能完成这项工作?
    • 相信你应该可以绑定DataTemplate
    • 我试过了,CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=DataTemplate}, Path=DataContext.CriteriaId}",但也没有用。
    • 天啊!我没有意识到 DataTemplate 没有 DataContext 属性。试试这个:{Binding Path=CriteriaId, RelativeSource={RelativeSource TemplatedParent}}。如果这不起作用,只需作弊并使用堆栈帧内的按钮。
    【解决方案2】:

    只要你的按钮的Tag 不为空(如果它为空,你就有不同的问题),我看不出你不能像你那样直接绑定到CriterionId 的原因Tag.

    【讨论】:

    • 嗨 Jakub,我在上面添加了一个 TextBlock,其绑定与 Button 的 Tag 相同,但 TextBlock 得到更新,而不是 Tag 或按钮的内容!
    • 哦我觉得肯定是和按钮的DataContext有关!
    猜你喜欢
    • 2011-05-27
    • 2012-12-15
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多