0

I have a CollectionViewSource (cvs) which has strongly typed DataTable as it's source. Cvs.View is set as DataGrid's ItemsSource. I want to update, insert and delete data from a database based on changes in DataGrid. I have successfully done update, and i have an idea for delete, but for insert i have some problems. I tried to do it by handling CurrentChanging event of cvs.View but row state is always Detached and it should be Added. Here is my code:

private void View_CurrentChanging(object sender, CurrentChangingEventArgs e)
{
    if (cvs.View.CurrentItem != null)
    {
        var dataRow = ((cvs.View.CurrentItem as DataRowView).Row) as MyDataSet.MyTableRow;
        if (dataRow.HasChanges())
        {
            //do update - works
        }
        dataRow.EndEdit(); // without this line RowState is Unchanged when it should be Added
        if (dataRow.RowState == DataRowState.Added)
        {
            //do insert - never goes here, RowState is Detached when it should be Added
        }
    }
}

Is this the right way to do it? Am I missing something? Thanks in advance.

EDIT: DataGrid binding:

dataGrid1.ItemsSource = cvs.View;
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Vale
  • 3,258
  • 2
  • 27
  • 43
  • pls leave the CollectionViewSource stuff out of your code and just try setting the itemssource direct to your DataTable. – blindmeis Jul 13 '11 at 11:08

3 Answers3

1

i use this the following in my wpf app:

this.MyView = (BindingListCollectionView)CollectionViewSource.GetDefaultView(this.MyDataTable);

as far as you do an insert, update or delete to your DataTable its automatic reflected in your View/Datagrid.

EDIT: MyView is the View you bind to your DataGrid in your UI

private BindingListCollectionView _view;

public BindingListCollectionView MyView 
{
    get { return this._view; }
    protected set
    {
        this._view = value;
        this.NotifyPropertyChanged(() => this.MyView);
    }
}

XAML

<DataGrid ItemsSource="{Binding Path=MyView, Mode=OneWay, ValidatesOnDataErrors=true, ValidatesOnExceptions=true}" />
blindmeis
  • 22,175
  • 7
  • 55
  • 74
  • I don't understand what is this.MyView here. – Vale Jul 13 '11 at 06:52
  • see my edit. you did not need to listen to the changing event of your view. – blindmeis Jul 13 '11 at 07:06
  • I understood most of it, but I get an exception on line this.NotifyPropertyChanged(() => this.MyView); - MainWindow does not contain definition for NotifyProperyChanged – Vale Jul 13 '11 at 07:25
  • Please explain this to me. I am stuck. I know how to do the same thing in forms, but not in wpf, it is so confusing. – Vale Jul 13 '11 at 07:59
  • this.NotifyPropertyChanged(() => this.MyView); is just the implementation of INotifyPropertyChanged. you can leave this if you set the itemssource just once. pls post your datagrid binding(xaml or code) – blindmeis Jul 13 '11 at 08:18
  • i assume that you do not use mvvm, thats ok but ... ;) setting dataGrid1.ItemsSource = this.MyView; should work. you can of course set the itemssource direct to your DataTable. dataGrid1.ItemsSource = this.MyDataTable; you can edit your data through the datagrid or in codebehind and all changes should be reflected. – blindmeis Jul 13 '11 at 11:02
0

It is an older post but I have another solution I think:

RowState="{Binding CurrentItem.Row.RowState}"

RowState is a dependency Property in my Control with type of DataRowState.

It is also neccessary to init the new Row correctly! For me works(And I think for others also):

DataRowView rv = dv.AddNew();
rv.EndEdit();

Hope this helps somebody!

gismo
  • 1
0

I came across the same strange behavior. If a datarow is detached and you get the row from BindingSource.Item (i.e datarowview) then calling EndEdit to the row does not add the row to the table. So as a workaround.

Instead of calling DataRow.EndEdit first check the RowState of the data row, if detached then manually add it to the table i.e:-

If Row.RowState=DataRowState.Detached Then
  Row.Table.Rows.Add(Row)
Else
  Row.EndEdit
End If