-->

How do I create a new row in WPF DataGrid when it

2019-01-23 15:14发布

问题:

I have a project with an XmlDataProvider bound to a WPF DataGrid control. I have the bindings on the DataGrid set up as follows:

<dg:DataGrid ItemsSource="{Binding Source={StaticResource XmlData}, XPath=Root/People/Person}"
             AutoGenerateColumns="False">
    <dg:DataGrid.Columns>
        <dg:DataGridTextColumn Header="ID" Binding="{Binding XPath=ID}"/>
        <dg:DataGridTextColumn Header="Name" Binding="{Binding XPath=Name}"/>
    </dg:DataGrid.Columns>
</dg:DataGrid>

Users can edit entries using the DataGrid without any problems. What I cannot manage to accomplish is allowing the user to add a new row (i.e. a new Person) using the DataGrid. How can I allow this?

回答1:

Make sure that you set: CanUserAddRows="True" and that the default constructor of a bound class is available.



回答2:

To add a row to a WPF DataGrid that is bound to an XmlDataSource, you need to directly modify the backing data store. You can use the DataGrid to collect the new row information from the user and then in the RowEditEnding event, you can add the row's information to your backing store and prevent the DataGrid from actually trying to commit the edit using its internal logic. Since the DataGrid is bound to the XmlDataSource, it will display the changes you made to the backing store.

Here is the general idea:

private void MyDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
  if (e.EditAction == DataGridEditAction.Cancel)
  {
    e.Cancel = false;
    return;
  }

  if (e.EditAction == DataGridEditAction.Commit)
  {
    DataGridRow dgr = e.Row;
    XmlElement xe = myXmlDataProvider.Document.CreateElement("NewRowElement");
    foreach(DataGridCell cell in dgr.Cells)
    {
      xe.SetAttribute(cell.Name, cell.Value);
    }
    dataProvider.Document.DocumentElement.AppendChild(xe);
    e.Cancel = true;
  }
}


回答3:

Have you tried setting CanUserAddRows="True" on the DataGrid?



回答4:

Is the problem that the user can't add rows or is it that when the user does add a row, it's not saved to the backing XML store? I can easily add a datagrid with CanUserAddRows="True" to a WPF application, bind the grid to an in-memory list and then have the user add rows that are reflected in that in-memory list. That makes me think that your problem is saving to the backing store.

When I bind to an XML on the file system, I can no longer add records to the data grid. I think you will need a minor workaround in that you read the file into an in-memory collection, bind to that and then update the file accordingly as users add rows.