Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Delete button in listview mvvm

Tags:

c#

mvvm

wpf

I have a button inside a listview to delete selected item.when i click on the button RemoveSubjectCommand is not firing. if i put the button outside the listview it is working fine. hopw this is just because of nested item. how can i solve this problem?

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

View Model,

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

If i put following code, it will work fine.

<ListView.InputBindings>
    <KeyBinding Key="Delete" Command="{Binding RemoveSubjectCommand}" />
</ListView.InputBindings>
like image 428
Chamika Sandamal Avatar asked Nov 27 '12 12:11

Chamika Sandamal


2 Answers

That is because DataContext of button is ListBoxItem DataContext. So you need to go to parent ListView DataContext.

one way to do that, is to give ListView a name, and to bind with element name

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

like image 56
Arsen Mkrtchyan Avatar answered Sep 29 '22 14:09

Arsen Mkrtchyan


You need to bind the Command to using FindAncestor. Otherwise, it'll try to bind to a RemoveSubjectCommand using the ListViewItem's datacontext, not the ViewModel's.

Try this:

<Button Content="X" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListView}, Path=DataContext.RemoveSubjectCommand}"  />
like image 44
Blachshma Avatar answered Sep 29 '22 14:09

Blachshma