Hi,
We've encountered a bit of a problem, when managing large amounts of data.
Very often we get a situation, where one (or more) property has to be set to a specific value
for many objects.
Let's say, we're in a listView of the object "Customer", who has property "Active"
there are 500 cutomers in a list view, and we want to set this property "Active" to "false"
for 50 customers. (selected by hand in a listView)
Proposed Solution:
As we see it, "the best" solution for this problem would be
to split a ListView, display a property grid on the rihgt side of the screen
and make it work Just like a property grid in Visual studio does.
meaning that - if one object is selected, it's data is displayed in the property grid
if many objects are selected, only properties that match, are displayed.
Upon changing a porperty value in a property grid, a corresponding property value,
would be updated in all selected objects.
ListView - How to edit multiple objects simultaneously (batch edit) via a property grid or a separate DetailView
Answers
Hello,
In the latest XAF versions, I recommend that you use NonPersistentObjectSpace and design non-persistent classes as described at eXpressApp Framework > Concepts > Business Model Design > Non-Persistent Objects. To manage persistent data (for lookups) in non-persistent objects, use the How to: Show Persistent Objects in a Non-Persistent Object's View approach. To show a View, use the Ways to Show a View approach (PopupWindowShowAction).
You can find a ready example code below (add this code into the MainDemo.Module project):
C#using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Editors;
using MainDemo.Module.BusinessObjects;
namespace MainDemo.Module.Controllers {
public class BatchEditInPopupListViewController : ObjectViewController<ListView, Contact> {
public PopupWindowShowAction BatchEditInPopup { get; private set; }
public BatchEditInPopupListViewController() {
TargetViewNesting = Nesting.Root;
BatchEditInPopup = new PopupWindowShowAction(this, "BatchEditInPopup", DevExpress.Persistent.Base.PredefinedCategory.Edit);
BatchEditInPopup.CustomizePopupWindowParams += BatchEditInPopup_CustomizePopupWindowParams;
BatchEditInPopup.Execute += BatchEditInPopup_Execute;
}
private void BatchEditInPopup_CustomizePopupWindowParams(object sender, CustomizePopupWindowParamsEventArgs e) {
IObjectSpace persistentObjectSpace = Application.CreateObjectSpace(typeof(Contact));
NonPersistentObjectSpace nonPersistentObjectSpace = (NonPersistentObjectSpace)e.Application.CreateObjectSpace(typeof(ContactBatchEditParameter));
nonPersistentObjectSpace.AdditionalObjectSpaces.Add(persistentObjectSpace);
ContactBatchEditParameter parameter = nonPersistentObjectSpace.CreateObject<ContactBatchEditParameter>();
DetailView dv = Application.CreateDetailView(nonPersistentObjectSpace, parameter, false);
dv.ViewEditMode = ViewEditMode.Edit;
e.View = dv;
e.View.Disposing += (s, args) => {
if(persistentObjectSpace != null) {
persistentObjectSpace.Dispose();
persistentObjectSpace = null;
}
};
}
private void BatchEditInPopup_Execute(object sender, PopupWindowShowActionExecuteEventArgs e) {
ContactBatchEditParameter parameter = (ContactBatchEditParameter)e.PopupWindowViewCurrentObject;
//Dennis: Iterating through the objects selected in the ListView.
foreach(Contact obj in e.SelectedObjects) {
obj.FirstName = parameter.FirstName;
obj.LastName = parameter.LastName;
obj.Manager = View.ObjectSpace.GetObject<Contact>(parameter.Manager);
}
//Dennis: Commit the changes made to the ListView ObjectSpace if this ListView is editable.
if(!View.AllowEdit.ResultValue) {
View.ObjectSpace.CommitChanges();
}
}
}
[DomainComponent]
public class ContactBatchEditParameter {
public string FirstName { get; set; }
public string LastName { get; set; }
public Contact Manager { get; set; }
}
}
Visual BasicImports DevExpress.ExpressApp
Imports DevExpress.ExpressApp.Actions
Imports DevExpress.ExpressApp.DC
Imports DevExpress.ExpressApp.Editors
Imports MainDemo.Module.BusinessObjects
Namespace MainDemo.Module.Controllers
Public Class BatchEditInPopupListViewController
Inherits ObjectViewController(Of ListView, Contact)
Private privateBatchEditInPopup As PopupWindowShowAction
Public Property BatchEditInPopup() As PopupWindowShowAction
Get
Return privateBatchEditInPopup
End Get
Private Set(ByVal value As PopupWindowShowAction)
privateBatchEditInPopup = value
End Set
End Property
Public Sub New()
TargetViewNesting = Nesting.Root
BatchEditInPopup = New PopupWindowShowAction(Me, "BatchEditInPopup", DevExpress.Persistent.Base.PredefinedCategory.Edit)
AddHandler BatchEditInPopup.CustomizePopupWindowParams, AddressOf BatchEditInPopup_CustomizePopupWindowParams
AddHandler BatchEditInPopup.Execute, AddressOf BatchEditInPopup_Execute
End Sub
Private Sub BatchEditInPopup_CustomizePopupWindowParams(ByVal sender As Object, ByVal e As CustomizePopupWindowParamsEventArgs)
Dim persistentObjectSpace As IObjectSpace = Application.CreateObjectSpace(GetType(Contact))
Dim nonPersistentObjectSpace As NonPersistentObjectSpace = CType(e.Application.CreateObjectSpace(GetType(ContactBatchEditParameter)), NonPersistentObjectSpace)
nonPersistentObjectSpace.AdditionalObjectSpaces.Add(persistentObjectSpace)
Dim parameter As ContactBatchEditParameter = nonPersistentObjectSpace.CreateObject(Of ContactBatchEditParameter)()
Dim dv As DetailView = Application.CreateDetailView(nonPersistentObjectSpace, parameter, False)
dv.ViewEditMode = ViewEditMode.Edit
e.View = dv
AddHandler e.View.Disposing, Sub(s, args)
If persistentObjectSpace IsNot Nothing Then
persistentObjectSpace.Dispose()
persistentObjectSpace = Nothing
End If
End Sub
End Sub
Private Sub BatchEditInPopup_Execute(ByVal sender As Object, ByVal e As PopupWindowShowActionExecuteEventArgs)
Dim parameter As ContactBatchEditParameter = CType(e.PopupWindowViewCurrentObject, ContactBatchEditParameter)
'Dennis: Iterating through the objects selected in the ListView.
For Each obj As Contact In e.SelectedObjects
obj.FirstName = parameter.FirstName
obj.LastName = parameter.LastName
obj.Manager = View.ObjectSpace.GetObject(Of Contact)(parameter.Manager)
Next obj
'Dennis: Commit the changes made to the ListView ObjectSpace if this ListView is editable.
If Not View.AllowEdit.ResultValue Then
View.ObjectSpace.CommitChanges()
End If
End Sub
End Class
<DomainComponent>
Public Class ContactBatchEditParameter
Public Property FirstName() As String
Public Property LastName() As String
Public Property Manager() As Contact
End Class
End Namespace
See Also:
Xafari FrameworkGroup (Bulk) Edit
Concepts > UI Construction > Views > List View Edit Modes (InlineEditMode = Batch)
Search keywords
batch, mass, edit, modify, update, change, multiple, several, selected, many, records, items, objects, ListView, at once, single, popup, modal, separate, window, separate, Action, set common value for property, column, non-persistent class, update persistent data
Hello Arnoldas,
I have updated a demo solution in this thread to version 10.2.8. I hope you find this information helpful.
See Also:
SystemModules - Make it possible to edit multiple records in an editable ListView at once and save the changes only when needed
BatchEntry - Support for massive manual data entry (Batch Entry)
Thanks,
Dennis
Thanks for the update.
Here's an idea of How this might work ;) http://mdworkstuff.blogspot.com/2010/08/multiedit-component-for-devexpress.html
Hello,
Thanks for the link. It looks like the solution I suggested previously does pretty same thing as in this blog;-)
Thanks,
Dennis