@(Html.DevExtreme().LoadPanel() .ID("loadPanel") .Position(p => p.Of("#gridContainer")) .Visible(false) ) @(Html.DevExtreme().DataGrid<DevExtreme.MVC.Demos.Models.Northwind.Order>() .ID("gridContainer") .KeyExpr("OrderID") .ShowBorders(true) .Pager(p => p.Visible(true)) .RepaintChangesOnly(true) .LoadPanel(loadPanel => loadPanel.Enabled(false)) .Editing(e => e .Mode(GridEditMode.Row) .AllowAdding(true) .AllowDeleting(true) .AllowUpdating(true) ) .Columns(columns => { columns.AddFor(m => m.OrderID).AllowEditing(false); columns.AddFor(m => m.ShipName); columns.AddFor(m => m.ShipCountry); columns.AddFor(m => m.ShipCity); columns.AddFor(m => m.ShipAddress); columns.AddFor(m => m.OrderDate).DataType(GridColumnDataType.Date); columns.AddFor(m => m.Freight); }) .OnOptionChanged("onOptionChanged") .OnSaving("onSaving") ) <div class="options"> <div class="caption">Options</div> <div class="option"> <span>Edit Row Key:</span> <div id="editRowKey">null</div> </div> <div class="option"> <span>Changes:</span> <div id="changes">[]</div> </div> </div> <script> var dataGrid, loadPanel; $(function () { dataGrid = $("#gridContainer").dxDataGrid("instance"); loadPanel = $("#loadPanel").dxLoadPanel("instance"); loadPanel.show(); sendRequest('@Url.HttpRouteUrl("DataGridWebApi", new { action = "Orders", skip = 700 })') .always(() => { loadPanel.hide(); }) .done((data) => { dataGrid.option("dataSource", data); }); }); function onOptionChanged(e) { if (e.name === "editing") { var editRowKey = e.component.option("editing.editRowKey"), changes = e.component.option("editing.changes"); $("#editRowKey").text(editRowKey === null ? "null" : editRowKey); changes = changes.map((change) => { return { type: change.type, key: change.type !== "insert" ? change.key : undefined, data: change.data }; }); $("#changes").text(JSON.stringify(changes, null, " ")); } }; function onSaving(e) { var change = e.changes[0]; if (change) { e.cancel = true; loadPanel.show(); e.promise = saveChange(change) .always(() => { loadPanel.hide(); }) .done((data) => { var orders = e.component.option("dataSource"); if (change.type === "insert") { change.data = data; } orders = DevExpress.data.applyChanges(orders, [change], { keyExpr: "OrderID" }); e.component.option({ dataSource: orders, editing: { editRowKey: null, changes: [] } }); }); } }; function saveChange(change) { switch (change.type) { case "insert": return sendRequest('@Url.HttpRouteUrl("DataGridWebApi", new { action = "InsertOrder" })', "POST", { values: JSON.stringify(change.data) }); case "update": return sendRequest('@Url.HttpRouteUrl("DataGridWebApi", new { action = "UpdateOrder" })', "PUT", { key: change.key, values: JSON.stringify(change.data) }); case "remove": return sendRequest('@Url.HttpRouteUrl("DataGridWebApi", new { action = "DeleteOrder" })', "DELETE", { key: change.key }); } }; function sendRequest(url, method, data) { var d = $.Deferred(); method = method || "GET"; $.ajax(url, { method: method, data: data, cache: false, xhrFields: { withCredentials: true } }).done(function (result) { d.resolve(method === "GET" ? result.data : result); }).fail(function (xhr) { d.reject(xhr.responseJSON ? xhr.responseJSON.Message : xhr.statusText); }); return d.promise(); }; </script>
using DevExtreme.MVC.Demos.Models; using DevExtreme.MVC.Demos.Models.DataGrid; using DevExtreme.MVC.Demos.Models.SampleData; using System; using System.Linq; using System.Web.Mvc; namespace DevExtreme.MVC.Demos.Controllers { public class DataGridController : Controller { public ActionResult EditStateManagement() { return View(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using Newtonsoft.Json; using System; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Formatting; using System.Web.Http; using DevExtreme.MVC.Demos.Models.Northwind; using DevExtreme.MVC.Demos.Models.DataGrid; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Controllers { [Route("api/DataGridWebApi/{action}", Name = "DataGridWebApi")] public class DataGridWebApiController : ApiController { InMemoryNorthwindContext _nwind = new InMemoryNorthwindContext(); [HttpGet] public HttpResponseMessage Orders(DataSourceLoadOptions loadOptions) { return Request.CreateResponse(DataSourceLoader.Load(_nwind.Orders, loadOptions)); } [HttpPost] public HttpResponseMessage InsertOrder(FormDataCollection form) { var values = form.Get("values"); var newOrder = new Order(); JsonConvert.PopulateObject(values, newOrder); Validate(newOrder); if(!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage()); _nwind.Orders.Add(newOrder); _nwind.SaveChanges(); return Request.CreateResponse(HttpStatusCode.Created, newOrder); } [HttpPut] public HttpResponseMessage UpdateOrder(FormDataCollection form) { var key = Convert.ToInt32(form.Get("key")); var values = form.Get("values"); var order = _nwind.Orders.First(o => o.OrderID == key); JsonConvert.PopulateObject(values, order); Validate(order); if(!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage()); _nwind.SaveChanges(); return Request.CreateResponse(HttpStatusCode.OK, order); } [HttpDelete] public void DeleteOrder(FormDataCollection form) { var key = Convert.ToInt32(form.Get("key")); var order = _nwind.Orders.First(o => o.OrderID == key); _nwind.Orders.Remove(order); _nwind.SaveChanges(); } // additional actions [HttpGet] public HttpResponseMessage OrderDetails(int orderID, DataSourceLoadOptions loadOptions) { return Request.CreateResponse(DataSourceLoader.Load( from i in _nwind.Order_Details where i.OrderID == orderID select new { Product = i.Product.ProductName, Price = i.UnitPrice, i.Quantity, Sum = i.UnitPrice * i.Quantity }, loadOptions )); } [HttpGet] public HttpResponseMessage ShippersLookup(DataSourceLoadOptions loadOptions) { var lookup = from i in _nwind.Shippers orderby i.CompanyName select new { Value = i.ShipperID, Text = i.CompanyName }; return Request.CreateResponse(DataSourceLoader.Load(lookup, loadOptions)); } [HttpGet] public HttpResponseMessage CustomersLookup(DataSourceLoadOptions loadOptions) { var lookup = from i in _nwind.Customers let text = i.CompanyName + " (" + i.Country + ")" orderby i.CompanyName select new { Value = i.CustomerID, Text = text }; return Request.CreateResponse(DataSourceLoader.Load(lookup, loadOptions)); } [HttpPost] public HttpResponseMessage Batch(List<DataChange> changes) { foreach(var change in changes) { Order order; if(change.Type == "update" || change.Type == "remove") { var key = Convert.ToInt32(change.Key); order = _nwind.Orders.First(o => o.OrderID == key); } else { order = new Order(); } if(change.Type == "insert" || change.Type == "update") { JsonConvert.PopulateObject(change.Data.ToString(), order); Validate(order); if(!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage()); if(change.Type == "insert") { _nwind.Orders.Add(order); } change.Data = order; } else if(change.Type == "remove") { _nwind.Orders.Remove(order); } } _nwind.SaveChanges(); return Request.CreateResponse(HttpStatusCode.OK, changes); } } }
using System; using System.Collections.Generic; using System.Data.Entity; namespace DevExtreme.MVC.Demos.Models.Northwind { public class InMemoryNorthwindContext : InMemoryDataContext<Order> { readonly NorthwindContext _nwind = new NorthwindContext(); public DbSet<Customer> Customers => _nwind.Customers; public DbSet<Order_Detail> Order_Details => _nwind.Order_Details; public ICollection<Order> Orders => ItemsInternal; public DbSet<Shipper> Shippers => _nwind.Shippers; protected override IEnumerable<Order> Source => _nwind.Orders; protected override int GetKey(Order item) => item.OrderID; protected override void SetKey(Order item, int key) => item.OrderID = key; } }
#gridContainer { height: 440px; } .options { padding: 20px; margin-top: 20px; background-color: rgba(191, 191, 191, 0.15); } .caption { margin-bottom: 10px; font-weight: 500; font-size: 18px; } .option { margin-bottom: 10px; } .option > span { position: relative; margin-right: 10px; } .option > div { display: inline-block; font-weight: bold; }