Ticket S132098
Visible to All Users

ListView - How to edit multiple objects simultaneously (batch edit) via a property grid or a separate DetailView

created 16 years ago

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.

Answers

created 16 years ago (modified 6 years ago)

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 Basic
Imports 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

    Show previous comments (1)
    Dennis Garavsky (DevExpress) 14 years ago

      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

      AZ AZ
      Arnoldas ZUKAUSKAS 14 years ago

        Thanks for the update.
        Here's an idea of How this might work ;) http://mdworkstuff.blogspot.com/2010/08/multiedit-component-for-devexpress.html

        Dennis Garavsky (DevExpress) 14 years ago

          Hello,
          Thanks for the link. It looks like the solution I suggested previously does pretty same thing as in this blog;-)
          Thanks,
          Dennis

          Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

          Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.