Delete a row in WPF DataGrid
Asked Answered
O

6

14

I have a datagrid with a delete icon as one column and update icon as another column. On click of update, the first cell is set on focus.

On click on delete I want to delete that selected row, but I get the error "Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead." with the following code:

XAML:

<DataGrid Name="grdList" Margin="3,16,0,5" RowHeight="30" ColumnWidth="*"
          ItemsSource="{Binding  List,Mode=TwoWay}" Width="434" 
          AutoGenerateColumns="False" 
          CanUserAddRows="False" AlternatingRowBackground="#FFB9BBFF">
    <DataGrid.Columns>
        <DataGridTextColumn MinWidth="0" Header="Property"
                            Binding="{Binding Path=Property}"/>

        <DataGridTemplateColumn Header="Update"  MinWidth="50" MaxWidth="50">
            <DataGridTemplateColumn.CellStyle>
                <Style TargetType="DataGridCell">
                    <EventSetter Event="PreviewMouseLeftButtonDown"
                                 Handler="EventSetter_OnHandler"/>
                </Style>
            </DataGridTemplateColumn.CellStyle>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Image Source="Icons/Update.jpg"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTemplateColumn Header="Delete"  MinWidth="50" MaxWidth="50">
            <DataGridTemplateColumn.CellStyle>
                <Style TargetType="DataGridCell">
                    <EventSetter Event="PreviewMouseLeftButtonDown"
                                 Handler="EventSetter_OnHandler"/>
                </Style>
            </DataGridTemplateColumn.CellStyle>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Image Source="Icons/Delete.jpg"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

C#:

private void EventSetter_OnHandler(object sender, MouseButtonEventArgs e)
{
    object source = e.OriginalSource;
    if (source.GetType() == typeof(Image))
    {
        grdList.IsReadOnly = false;

        selectedRow = FindParent<DataGridRow>(sender as DependencyObject);

        if (((DataGridCell)sender).Column.Header.ToString().ToUpperInvariant() == "DELETE")
        {
            grdList.Items.Remove(selectedRow);
        }
        else
        {
            DataGridCellsPanel panel = FindVisualChild<DataGridCellsPanel>(selectedRow);

            DataGridCell dgc = panel.Children[0] as DataGridCell; 
            dgc.Focus();
            grdList.BeginEdit();

            e.Handled = true;
        }
    }
}

Also How to add the delete function with the "Delete" key together with the click on the delete cell.

Ormuz answered 1/7, 2014 at 19:26 Comment(0)
S
5

I suspect on Delete i.e. in EventSetter_OnHandler, you must be removing items from the Items collection of dataGrid. Something like this:

grdList.Items.Remove(someItem);

But as the error is self explanatory

"Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead."

You have binded ItemsSource to some collection, so you need to remove item from it. You can't modify the Items collection directly when binding ItemsSource with some collection. It should be something like:

List.Remove(someItem);
Sanctus answered 1/7, 2014 at 19:30 Comment(1)
Thanks.. Is it possible to initiate the default delete option in WPF datagrid on the click?Ormuz
I
2

You can bind the SelectedItem of your DataGrid to a property. Then you can call

List.Remove(SelectedDataGridItem);

SelectedDataGridItem is the property which the Selected Item is bound to

Impromptu answered 1/7, 2014 at 19:36 Comment(0)
B
2

Try this,

grdList.Items.RemoveAt(grdList.SelectedIndex);
Baird answered 20/1, 2015 at 10:28 Comment(2)
Though probably a fine answer, try to avoid code-only responses. Consider adding an explanationAnathema
Has the same problems as 'Remove'. Not allowed if 'ItemsSource' is bound to a collection.Breakthrough
P
2

I had the same Problem, i solved it so:

yourrowbindingobject row = (yourrowbindingobject)yourdatagrid.SelectedItems[0];

ObservableCollection<yourrowbindingobject> data = (ObservableCollection<yourrowbindingobject>)yourdatagrid.ItemsSource;
data.Remove(row);
Pinkeye answered 29/8, 2016 at 9:29 Comment(0)
C
0

I had the same problem when trying to remove a datagrid row using button click, I solved it as below:

Datagrid rows populated by data retrieved from SQL database:

/* Assign ItemsSource of DataGrid. */
dataGridSupplier.ItemsSource = Ldtbl.DefaultView;

 DataRowView dr = dataGridSupplier.SelectedItem as DataRowView;
 DataRow dr1 = dr.Row;

/* Remove selected item from the datagrid after successfully updating database. */
Ldtbl.Rows.Remove(dr1);
Creamcups answered 29/4, 2021 at 13:45 Comment(0)
B
0

I stumbled upon this and found a simpler solution by "refreshing" the itemSources list.

private void Delete_Click(object sender, RoutedEventArgs e)
{
    for (var visObj = sender as Visual; visObj != null; visObj = VisualTreeHelper.GetParent(visObj) as Visual)
    {
        if (visObj is DataGridRow)
        {
            DataGridRow row = (DataGridRow)visObj;
            int clickedIdx = row.GetIndex();

            // deleting starts here:
            myDataList.RemoveAt(clickedIdx);
            var temp = myDataGrid.ItemsSource;
            myDataGrid.ItemsSource = null;
            myDataGrid.ItemsSource = temp;
        }
    }
}
Boraginaceous answered 20/6, 2024 at 11:18 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.