This example shows how to bind the WinForms Data Grid control to a BindingSource
that gets data from OData services.
Unlike the Entity Framework data context, the OData service context does not have automatic change tracking (you must track changes manually). This example demonstrates how to handle grid events to track user edits.
Each time the user changes the value in a cell and commits the row, the GridView
raises the RowUpdated event. Handle this event to notify the data context about the change. When a row has been deleted, the GridView
raises the RowDeleted event.
C#private void GridView_RowUpdated(object sender, RowObjectEventArgs e) {
if (e.RowHandle == GridControl.NewItemRowHandle) {
this.Context.AddToOrders((Order)e.Row);
} else {
this.Context.UpdateObject(e.Row);
}
}
private void GridView_RowDeleted(object sender, RowDeletedEventArgs e) {
this.Context.DeleteObject(e.Row);
}
Visual BasicPrivate Sub GridView_RowUpdated(sender As Object, e As RowObjectEventArgs) Handles GridView1.RowUpdated
If e.RowHandle = GridControl.NewItemRowHandle Then
Me.Context.AddToOrders(CType(e.Row, Order))
Else Me.Context.UpdateObject(e.Row)
End If
End Sub
Private Sub GridView_RowDeleted(sender As Object, e As RowDeletedEventArgs) Handles GridView1.RowDeleted
Me.Context.DeleteObject(e.Row)
End Sub
Files to Review
- MainForm.cs (VB: MainForm.vb)
- WebApiConfig.cs (VB: WebApiConfig.vb)
- CustomersController.cs (VB: CustomersController.vb)
- OrdersController.cs (VB: OrdersController.vb)
- Customer.cs (VB: Customer.vb)
- DataContext.cs (VB: DataContext.vb)
- Order.cs (VB: Order.vb)
Documentation
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using DevExpress.Data;
using DevExpress.XtraBars;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using DxSample.Service.Models;
using System;
using System.Linq;
namespace DxSample {
public partial class MainForm : XtraForm {
Default.Container Context = new Default.Container(new Uri("http://localhost:50936/"));
public MainForm() {
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e) {
this.customerBindingSource.DataSource = this.Context.Customers.ToList();
this.orderBindingSource.DataSource = this.Context.Orders.ToList();
}
private void GridView_RowUpdated(object sender, RowObjectEventArgs e) {
if (e.RowHandle == GridControl.NewItemRowHandle)
this.Context.AddToOrders((Order)e.Row);
else this.Context.UpdateObject(e.Row);
}
private void GridView_RowDeleted(object sender, RowDeletedEventArgs e) {
this.Context.DeleteObject(e.Row);
}
private void SaveButton_ItemClick(object sender, ItemClickEventArgs e) {
this.Context.SaveChanges();
}
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using DxSample.Service.Models;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
namespace DxSample.Service
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Customer>("Customers");
builder.EntitySet<Order>("Orders");
config.MapODataServiceRoute("ODataRoute", null, builder.GetEdmModel());
}
}
}
C#using DxSample.Service.Models;
using System.Linq;
using System.Web.Http;
using System.Threading.Tasks;
using System.Net;
using System.Web.OData;
namespace DxSample.Service.Controllers {
public class CustomersController :ODataController {
private bool CustomerExists(int key) {
return DataContext.Customers.Any(c => c.ID == key);
}
[EnableQuery]
public IQueryable<Customer> Get() {
return DataContext.Customers;
}
[EnableQuery]
public SingleResult<Customer> Get([FromODataUri] int key) {
IQueryable<Customer> result = DataContext.Customers.Where(c => c.ID == key);
return SingleResult.Create(result);
}
public async Task<IHttpActionResult> Post(Customer customer) {
if (!this.ModelState.IsValid) return this.BadRequest(this.ModelState);
customer = await DataContext.AddCustomer(customer.Name);
return this.Created(customer);
}
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Customer> customer) {
if (!this.ModelState.IsValid) return this.BadRequest(this.ModelState);
Customer entity = await DataContext.FindCustomerAsync(key);
if (entity == null) return this.NotFound();
customer.Patch(entity);
return this.Updated(entity);
}
public async Task<IHttpActionResult> Put([FromODataUri] int key, Customer update) {
if (!this.ModelState.IsValid) return this.BadRequest(this.ModelState);
if (key != update.ID) return this.BadRequest();
await DataContext.UpdateCustomer(update);
return this.Updated(update);
}
public async Task<IHttpActionResult> Delete([FromODataUri] int key) {
Customer customer = await DataContext.FindCustomerAsync(key);
if (customer == null) return this.NotFound();
await DataContext.RemoveCustomer(customer);
return this.StatusCode(HttpStatusCode.NoContent);
}
}
}
C#using DxSample.Service.Models;
using System.Linq;
using System.Web.Http;
using System.Threading.Tasks;
using System.Net;
using System.Web.OData;
namespace DxSample.Service.Controllers {
public class OrdersController : ODataController {
private bool OrderExists(int key) {
return DataContext.Orders.Any(c => c.ID == key);
}
[EnableQuery]
public IQueryable<Order> Get() {
return DataContext.Orders;
}
[EnableQuery]
public SingleResult<Order> Get([FromODataUri] int key) {
IQueryable<Order> result = DataContext.Orders.Where(c => c.ID == key);
return SingleResult.Create(result);
}
public async Task<IHttpActionResult> Post(Order order) {
if (!this.ModelState.IsValid) return this.BadRequest(this.ModelState);
order = await DataContext.AddOrder(order.Name, order.CustomerID);
return this.Created(order);
}
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Order> order) {
if (!this.ModelState.IsValid) return this.BadRequest(this.ModelState);
Order entity = await DataContext.FindOrderAsync(key);
if (entity == null) return this.NotFound();
order.Patch(entity);
return this.Updated(entity);
}
public async Task<IHttpActionResult> Put([FromODataUri] int key, Order update) {
if (!this.ModelState.IsValid) return this.BadRequest(this.ModelState);
if (key != update.ID) return this.BadRequest();
await DataContext.UpdateOrder(update);
return this.Updated(update);
}
public async Task<IHttpActionResult> Delete([FromODataUri] int key) {
Order order = await DataContext.FindOrderAsync(key);
if (order == null) return this.NotFound();
await DataContext.RemoveOrder(order);
return this.StatusCode(HttpStatusCode.NoContent);
}
}
}
C#using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DxSample.Service.Models {
public static class DataContext {
private static readonly List<Customer> ListCustomers;
private static readonly List<Order> ListOrders;
private static int CustomersCounter;
private static int OrdersCounter;
private static readonly object Sync = new object();
static DataContext() {
DataContext.ListCustomers = new List<Customer>();
DataContext.ListOrders = new List<Order>();
DataContext.CustomersCounter = 1;
DataContext.OrdersCounter = 1;
DataContext.AddCustomer("John");
DataContext.AddCustomer("Bob");
DataContext.AddOrder("Chai", 1);
DataContext.AddOrder("Chang", 1);
DataContext.AddOrder("Queso Caprale", 2);
}
public static IQueryable<Customer> Customers {
get { return DataContext.ListCustomers.AsQueryable(); }
}
public static IQueryable<Order> Orders {
get { return DataContext.ListOrders.AsQueryable(); }
}
public static Task<Customer> AddCustomer(string name) {
return Task.Run<Customer>(() => {
lock (DataContext.Sync) {
Customer result = new Customer() { ID = DataContext.CustomersCounter++, Name = name };
DataContext.ListCustomers.Add(result);
return result;
}
});
}
public static Task<Order> AddOrder(string name, int customerID) {
return Task.Run<Order>(() => {
lock (DataContext.Sync) {
Order result = new Order() { ID = DataContext.OrdersCounter++, Name = name, CustomerID = customerID };
DataContext.ListOrders.Add(result);
return result;
}
});
}
public static Task<Customer> FindCustomerAsync(int key) {
return Task.Run<Customer>(() => DataContext.Customers.SingleOrDefault(c => c.ID == key));
}
public static Task<Order> FindOrderAsync(int key) {
return Task.Run<Order>(() => DataContext.Orders.SingleOrDefault(o => o.ID == key));
}
public static Task UpdateCustomer(Customer customer) {
return Task.Run(() => {
Customer original = DataContext.Customers.Single(c => c.ID == customer.ID);
int index = DataContext.ListCustomers.IndexOf(original);
DataContext.ListCustomers[index] = customer;
});
}
public static Task UpdateOrder(Order order) {
return Task.Run(() => {
Order original = DataContext.Orders.Single(o => o.ID == order.ID);
int index = DataContext.ListOrders.IndexOf(original);
DataContext.ListOrders[index] = order;
});
}
public static Task RemoveCustomer(Customer customer) {
return Task.Run(() => DataContext.ListCustomers.Remove(customer));
}
public static Task RemoveOrder(Order order) {
return Task.Run(() => DataContext.ListOrders.Remove(order));
}
}
}