The ASPxGridListEditor does not natively support multi-row editing. It is recommended to either use the single-row inline editing by setting the AllowEdit property of the ListView model to True in the Model Editor, or edit objects in a DetailView. The multi-row editing functionality is rarely required, but since our customers usually experience difficulties implementing it, I decided to create this example.
- we already use DataItem templates to show data in grid cells.
1. Creates an ASPxCallback control and adds it to a page. This control is used to send callbacks from client-side editors used in grid cells.
2. Replaces the default DataItemTemplate with a custom one (EditItemTemplate). The custom template is required to show editors for the user input in grid cells. This template is based on the DataItemTemplate class used in XAF by default. The only difference is that controls from this template are always in the Edit mode.
3. Assigns the client-side script that performs a callback when the value is changed to the editors added to grid cells via the custom DataItemTemplate. This is done in the editor's Init event handler, because at this moment, the NamingContainer that contains the key of the bound object is available.
4. Handles the callback sent from the client side and changes the value of a corresponding object's property.
I recommend that you review the following help topics for additional information:
Question Comments
Added By:
Yuriy Konytskyy at:
6/3/2013 3:44:39 AM I doesn't work in v12.2.10
Added By:
Anatol (DevExpress Support) at:
7/1/2013 4:19:13 AM I have updated the example. Please see implementation details for version 13.1.
Added By:
Sandro Welter (Intelligix) at:
7/5/2013 3:02:00 PM I'm getting the error below.
The error occurred:
Type: NullReferenceException
Message: Object reference not set to an instance of an object.
Data: 0 entries
Stack trace:
Added By:
Anatol (DevExpress Support) at:
1/10/2014 8:32:12 AM The NullReferenceException issue is solved.
Added By:
PHN at:
1/30/2014 10:55:55 AM Hi,
I have some modifications to support ASPxDateTimePropertyEditor,ASPxLookupPropertyEditor:
using System;
using System.Linq;
using System.ComponentModel;
using System.Web.UI;
using DevExpress.ExpressApp.Web.Editors.ASPx;
using DevExpress.Web.ASPxGridView;
using DevExpress.ExpressApp.Web;
using DevExpress.ExpressApp.Editors;
using DevExpress.Web.ASPxClasses;
using DevExpress.ExpressApp.DC;
using DevExpress.Web.ASPxCallback;
using DevExpress.ExpressApp.Model;
using System.Web.UI.WebControls;
using DevExpress.Web.ASPxEditors;
using DevExpress.Xpo;
using DevExpress.ExpressApp;
namespace WebExample.Module.Web
{
[ListEditor(typeof(object), false)]
public class MultiEditASPxGridListEditor : ASPxGridListEditor
{
const String CallbackArgumentFormat = "function (s, e) {{ {0}.PerformCallback(\"{1}|{2}|\" + {3}); }}"; // ASPxCallback, key, fieldName, value
public MultiRowEditASPxGridListEditor(IModelListView model)
: base(model) { }
ASPxCallback callback;
protected override object CreateControlsCore()
{
Panel panel = new Panel();
callback = new ASPxCallback();
callback.ID = ObjectTypeInfo.Type.Name + "aspxCallback1";
callback.ClientInstanceName = ObjectTypeInfo.Type.Name + "_callback1";
callback.Callback += new CallbackEventHandler(callback_Callback);
panel.Controls.Add(callback);
ASPxGridView grid = (ASPxGridView)base.CreateControlsCore();
grid.HtmlDataCellPrepared += new ASPxGridViewTableDataCellEventHandler(grid_HtmlDataCellPrepared);
panel.Controls.Add(grid);
return panel;
}
void grid_HtmlDataCellPrepared(object sender, ASPxGridViewTableDataCellEventArgs e)
{
if (e.DataColumn is GridViewDataColumnWithInfo && IsColumnSupported(((GridViewDataColumnWithInfo)e.DataColumn).Model))
{
e.Cell.Attributes["onclick"] = RenderHelper.EventCancelBubbleCommand;
}
}
protected override ITemplate CreateDataItemTemplate(IModelColumn columnInfo)
{
if (IsColumnSupported(columnInfo))
{
EditModeDataItemTemplate editModeTemplate = (EditModeDataItemTemplate)CreateDefaultColumnTemplate(columnInfo, this, ViewEditMode.Edit);
editModeTemplate.PropertyEditor.ImmediatePostData = false;
editModeTemplate.CustomCreateCellControl += new EventHandler<DevExpress.ExpressApp.Web.Editors.CustomCreateCellControlEventArgs>(editModeTemplate_CustomCreateCellControl);
return editModeTemplate;
}
else
{
return base.CreateDataItemTemplate(columnInfo);
}
}
void editModeTemplate_CustomCreateCellControl(object sender, DevExpress.ExpressApp.Web.Editors.CustomCreateCellControlEventArgs e)
{
if (e.PropertyEditor.Editor is ASPxWebControl)
{
e.PropertyEditor.Editor.Init += new EventHandler((s, args) => Editor_Init(s, args, e.PropertyEditor.Editor));
}
else if (e.PropertyEditor is ASPxLookupPropertyEditor)
{
ASPxLookupPropertyEditor editor = e.PropertyEditor as ASPxLookupPropertyEditor;
editor.DropDownEdit.DropDown.Init += new EventHandler((s, args) => Editor_Init(s, args, e.PropertyEditor.Editor));
}
}
void Editor_Init(object sender, EventArgs e,WebControl baseEditor)
{
ASPxWebControl editor = (ASPxWebControl)sender;
editor.Init -= new EventHandler((s, args) => Editor_Init(s, args, baseEditor));
// Uncomment to remove editors borders
//editor.Border.BorderStyle = BorderStyle.None;
GridViewDataItemTemplateContainer container = baseEditor.NamingContainer as GridViewDataItemTemplateContainer;
var columnInfo = container.Column as GridViewDataColumnWithInfo;
editor.SetClientSideEventHandler("ValueChanged", String.Format(CallbackArgumentFormat,
callback.ClientInstanceName, container.KeyValue, columnInfo.Model.PropertyName, editor is ASPxDateEdit ? "s.GetText()" : "s.GetValue()"));
}
void callback_Callback(object source, DevExpress.Web.ASPxCallback.CallbackEventArgs e)
{
String[] p = e.Parameter.Split('|');
Object key = TypeDescriptor.GetConverter(ObjectTypeInfo.KeyMember.MemberType).ConvertFromString(p[0]);
IMemberInfo member = ObjectTypeInfo.FindMember(p[1]);
Object value = null;
if (typeof(IXPSimpleObject).IsAssignableFrom(member.MemberType))
{
Type memberKeyType = XafTypesInfo.Instance.FindTypeInfo(member.MemberType).KeyMember.MemberType;
int index1 = p[2].LastIndexOf("(");
int index2 = p[2].LastIndexOf(")");
if (index1 > 0 && index2 > index1)
{
string memberKeyText = p[2].Substring(index1 + 1, index2 - index1 - 1);
value = ObjectSpace.GetObjectByKey(member.MemberType, Convert.ChangeType(memberKeyText, memberKeyType));
}
}
else
{
value = TypeDescriptor.GetConverter(member.MemberType).ConvertFromString(p[2]); ;
}
object obj = ObjectSpace.GetObjectByKey(ObjectTypeInfo.Type, key);
member.SetValue(obj, value);
ObjectSpace.CommitChanges();
}
private Type[] supportedPropertyEditorTypes()
{
return new Type[]{
typeof(ASPxStringPropertyEditor),
typeof(ASPxIntPropertyEditor),
typeof(ASPxBooleanPropertyEditor),
typeof(ASPxEnumPropertyEditor),
typeof(ASPxDateTimePropertyEditor),
typeof(ASPxLookupPropertyEditor)
};
}
protected virtual bool IsColumnSupported(IModelColumn model)
{
if (model.GroupIndex >= 0)
{
return false;
}
foreach (Type type in supportedPropertyEditorTypes())
{
if (type.IsAssignableFrom(model.PropertyEditorType))
{
return true;
}
}
return false;
}
// Sorting and grouping are not supported
protected override ColumnWrapper AddColumnCore(IModelColumn columnInfo)
{
ASPxGridViewColumnWrapper columnWrapper = (ASPxGridViewColumnWrapper)base.AddColumnCore(columnInfo);
if (IsColumnSupported(columnWrapper.Column.Model))
{
columnWrapper.Column.Settings.AllowSort = DevExpress.Utils.DefaultBoolean.False;
columnWrapper.Column.Settings.AllowGroup = DevExpress.Utils.DefaultBoolean.False;
}
return columnWrapper;
}
}
}
Added By:
Anatol (DevExpress Support) at:
1/31/2014 12:04:45 AM Thank you for sharing your code. It looks good. I hope it will be useful for others.
Added By:
Apostolis Bekiaris (DevExpress) at:
2/17/2014 7:12:23 AM Added in eXpandFramework 13.2.7.4
Added By:
HEUNGGI LEE at:
6/4/2014 6:10:47 AM Hi,
Is it possible to set width length on each column in GridView? It is ugly...especially Character field grid width is too narrow ..
Added By:
Anatol (DevExpress Support) at:
6/5/2014 7:42:58 AM Yes, this is possible - see
Adjust column width in listviews on the Web.Added By:
HEUNGGI LEE at:
6/18/2014 9:48:18 PM Hi PHN,
I tried with your code but list grid view does not show correctly row items. Last row has same pointer with before last row item.