user1399377
user1399377

Reputation: 479

Delete command from the datagrid is not working

I am binding some records with a data template button for deleting the selected row's record in a WPF datagrid. Well my problem is that delete command is not working.I really don't know why its not working despite putting every thing right. Please have a look in the code and tell me what i am doing wrong. Your little effort will make my work done. Thanks

<Window x:Class="DemoMVVM.View.EmployeeDetails"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewModel="clr-namespace:DemoMVVM.ViewModel"
    Title="EmployeeDetails" Height="200" Width="500">
<Window.DataContext>
    <viewModel:EmployeeDetailsViewModel></viewModel:EmployeeDetailsViewModel>
</Window.DataContext>
<Grid>
    <DataGrid  AutoGenerateColumns="False" CanUserAddRows="False" ItemsSource="{Binding EmpDetailsList}" Grid.Column="0"  SelectedItem="{Binding SelectedRecord,Mode=TwoWay}" Margin="10,17,10,8" >

        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=Id}" IsReadOnly="True" Visibility="Collapsed" Width="90"></DataGridTextColumn>
            <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" IsReadOnly="True" Width="*"></DataGridTextColumn>
            <DataGridTextColumn Header="Age" Binding="{Binding Path=Age}"  IsReadOnly="True" Width="*"></DataGridTextColumn>
            <DataGridTextColumn Header="City" Binding="{Binding Path=City}"  IsReadOnly="True" Width="*"></DataGridTextColumn>            
            <DataGridTemplateColumn Header="Delete" Width="60" IsReadOnly="True">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Delete" Command="{Binding Path=DeleteCommand}" ></Button>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>               
        </DataGrid.Columns>
    </DataGrid>
</Grid>

public class EmployeeDetailsViewModel
{
    private ObservableCollection<EmployeeModel> _empDetailsList;
    private EmployeeModel _selectedEmp;
    private RelayCommand _deleteCommand;

   public EmployeeDetailsViewModel()
   {
       _empDetailsList = new ObservableCollection<EmployeeModel>()
      {
          new EmployeeModel(){Id=1,Name="ABC",Age=26,City="Las Vegas"},
          new EmployeeModel(){Id=2,Name="MNO",Age=27,City="New Delhi"},
          new EmployeeModel(){Id=3,Name="XYZ",Age=25,City="Sydney"},
      };
   }

   public ObservableCollection<EmployeeModel> EmpDetailsList
   {
       get { return _empDetailsList; }
   }

   public ICommand DeleteCommand
   {
       get
       {
           if (_deleteCommand == null)
               _deleteCommand = new RelayCommand(Delete);
           return _deleteCommand;
       }
   }

   private void Delete()
   { 
   }
}

Relay Command Class`internal class RelayCommand : ICommand { #region Fields

    readonly Action _execute;
    readonly Func<bool> _canExecute;

    #endregion

    #region Constructors


    public RelayCommand(Action execute)
        : this(execute, null)
    {
    }

    public RelayCommand(Action execute, Func<bool> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion // Constructors

    #region ICommand Members

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute();
    }

    public event EventHandler CanExecuteChanged
    {
        add
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested += value;
        }
        remove
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested -= value;
        }
    }

    public void Execute(object parameter)
    {
        _execute();
    }

    #endregion // ICommand Members
}`

Upvotes: 2

Views: 2825

Answers (2)

Scroog1
Scroog1

Reputation: 3589

The issue is that the binding you've used means that it is expecting DeleteCommand to be a property of EmployeeModel rather than EmployeeDetailsViewModel.

Perhaps something like the following might work (just an outline) - assuming that the ListPresenter will need to do the deleting from the list and know which item to remove:

public class EmployeeDetailsListPresenter : INotifyPropertyChanged
{
    _empDetailsList = new ObservableCollection<EmployeeDetailsPresenter>
        {
            new EmployeeDetailsPresenter(new EmployeeModel(...), Delete),
            ...
        };

    public IEnumerable<EmployeeDetailsPresenter> EmpDetailsList { ... }

    private void Delete(EmployeeDetailsPresenter employeeDetails)
    {
        _empDetailsList.Remove(employeeDetails);
    }
}

public class EmployeeDetailsPresenter : INotifyPropertyChanged
{
    public EmployeeDetailsPresenter(EmployeeModel employee,
                                    Action<EmployeeDetailsPresenter> delete)
    {
        _employee = employee;
        _delete = delete;
    }

    public ICommand DeleteCommand
    {
        get
        {
            return new RelayCommand(() => _delete(this))
        }
    }
}

Upvotes: 3

David Bekham
David Bekham

Reputation: 2175

You may use the below code which simply resolves your error in xaml... I have just made the small changes in your xaml to resolve this..

        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=Id}" IsReadOnly="True" Visibility="Collapsed" Width="90"></DataGridTextColumn>
            <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" IsReadOnly="True" Width="*"></DataGridTextColumn>
            <DataGridTextColumn Header="Age" Binding="{Binding Path=Age}"  IsReadOnly="True" Width="*"></DataGridTextColumn>
            <DataGridTextColumn Header="City" Binding="{Binding Path=City}"  IsReadOnly="True" Width="*"></DataGridTextColumn>            
            <DataGridTemplateColumn Header="Delete" Width="60" IsReadOnly="True">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Delete" Command="{Binding Path=DataContext.DeleteCommand}" ></Button>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>               
        </DataGrid.Columns>
    </DataGrid>
</Grid>

Upvotes: 1

Related Questions