9
votes

I'm not good at English because I'm not a native speaker. I apologize if I've made mistakes in the language :)

I'm new in C# and WPF and I'm trying to bind a WPF DataGrid to a DataTable in TwoWay. Now when I edit the values in the DataGrid, data in the DataTable change correctly. When I try to fill the DataTable with the following code:

OleDbDataAdapter adapter = new OleDbDataAdapter("a query", (a connection));
adapter.Fill(dataTable);

the code works and the DataGrid seems all right. But when I try this:

dataTable.Rows[0][1] = (some object);

the display value doesn't change. I try to check the values in the DataGrid in the following way:

MessageBox.Show((SomeDataGrid.Items[0] as DataRowView).Row[1].ToString());

and it turns out no problem. I'm wondering why the display values are like this.

Here's my DataGrid.CellStyle in XAML:

<DataGrid.CellStyle>
    <Style TargetType="DataGridCell">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DataGridCell">
                    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{TemplateBinding Background}">
                        <DataGridDetailsPresenter HorizontalAlignment="Stretch" VerticalAlignment="Center" Content="{TemplateBinding Content}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <!-- triggers -->
        </Style.Triggers>
    </Style>
</DataGrid.CellStyle>

I've been stuck on this problem for several days. Thanks for any help!

3
When you define the column for DataGrid, Make sure you are setting the UpdateMode property to PropertyChangedSivakumar

3 Answers

6
votes

I am not very sure if this solution will work but it is worth a try.

Instead of binding your DataGrid to a DataTable, try binding it to a DataView . You can convert your DataTable to a DataView using DefaultView property like

DataTable dt = new DataTable();
DataView dv = dt.DefaultView;

On binding with DataView your notification to changes in data should work both ways.

6
votes

This works, maybe you can give some more info

viewmodel:

public DataTable MyDataTable { get; private set; }

//ctor
_ds = new DataSet("Test");
this.MyDataTable = _ds.Tables.Add("DT");
this.MyDataTable.Columns.Add("First");
this.MyDataTable.Columns.Add("Second");

this.MyDataTable.Rows.Add("11", "12");
this.MyDataTable.Rows.Add("21", "22");

//view is updated with this
public void UpdateTable()
{
    this.MyDataTable.Rows[0][1] = "haha";
}

xaml

<DataGrid AutoGenerateColumns="True" ItemsSource="{Binding MyDataTable}"/>
2
votes

Unfortunately, I don't believe the DataRow implements INotifyPropertyChanged or the DataTable implements INotifyCollectionChanged. These are the interface that tell a WPF DataBinding to update when the underlying source value changes. So when you update the underlying DataTable values, the Binding is not automatically refreshed and the change won't be reflected in your DataGrid.

This link points to a similar question and provides an answer. Basically, if you want your DataGrid to recognize and update when you change values in the underlying data source, you'll need to create a custom object/objects that implement INotifyPropertyChanged.