Reputation: 479
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
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
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