1

I want to delete a row in ListView Control using Command and CommandParameter like below.

<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>

I am trying to grab the Tag property of the Button and pass it to Command like above and than remove it from list like so.

Edited, above XAML and added a TextBlock which uses the same binding as the Button's Tag and Content, but somehow Button doesn't get the value but TextBlock does!?

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

but I always get criterionId parameter as null.

What am I doing wrong?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Pak
  • 125
  • 3
  • 13

2 Answers2

0

As long as your button's Tag isn't null (if it is null, you have a different problem), I don't see a reason that you can't bind directly to CriterionId like you do with Tag.

Jakub
  • 534
  • 3
  • 17
  • Hi Jakub, I added a TextBlock above with the same Binding as Button's Tag, but the TextBlock gets updated and not the Tag or the Content of the button! – Pak Aug 05 '11 at 17:09
  • Oh I think it must be something to do with the DataContext of the button! – Pak Aug 05 '11 at 17:12
0

Since you're explicitly setting the DataContext within the button, when you're doing a binding like {Binding SomeProperty} it will assume that SomeProperty is in the DataContext that you just set. Try using a more explicit binding like:

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

which will give you the correct DataContext's CriteriaID like it is for the TextBlock.

Jakub
  • 534
  • 3
  • 17
  • Yes that worked :). But just a little correction `"{Binding RelativeSource={RelativeSource AncestorType=StackPanel}, Path=DataContext.CriteriaId}"`. Thanks a Bunch Jakub. – Pak Aug 05 '11 at 17:38
  • Jakub, I had added the StackPanel to accommodate TextBlock. Now that I won't need TextBlock, I won't need the StackPanel either. In that case, If I set Path="GridViewColumn" in the answer your suggested, it doesn't work. Do I have to keep the StackPanel to make this work? – Pak Aug 05 '11 at 17:47
  • I believe you should be able to bind to the `DataTemplate` – Jakub Aug 05 '11 at 17:47
  • I tried this, `CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=DataTemplate}, Path=DataContext.CriteriaId}"` but it didn't work either. – Pak Aug 05 '11 at 17:51
  • D'oh! I didn't realize `DataTemplate` doesn't have a `DataContext` property. Try this: `{Binding Path=CriteriaId, RelativeSource={RelativeSource TemplatedParent}}`. If that doesn't work, just cheat and use a button inside a stackframe. – Jakub Aug 05 '11 at 17:56
  • nope, it didn't work. so i guess I'll have to stick with the StackPanel for now :). Thank you very much for all your help. – Pak Aug 05 '11 at 18:08