Ticket T634375
Visible to All Users

How to refresh data in the View after the Open Related Record action is executed

created 7 years ago (modified 7 years ago)

When the Open Related Object action is executed, DetailView is shown. After changing data and executing Save And Close Action in this DetailView, the source View shows a corresponding reference property value unchanged.

Answers approved by DevExpress Support

created 7 years ago (modified 7 years ago)

To show changes after an object's DetailView is closed, use the following workaround:

C#
using System; using System.Collections.Generic; using System.Linq; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Win.Editors; using DevExpress.XtraGrid.Columns; using DevExpress.ExpressApp.Win.SystemModule; using DevExpress.ExpressApp.Editors; namespace MainDemo.Module.Win.Controllers { class RefreshDataInOwnerObjectViewController : ViewController<DetailView> { private View ownerView; private object objectToOpen; public RefreshDataInOwnerObjectViewController(View ownerView, object objectToOpen) : base() { this.ownerView = ownerView; this.objectToOpen = objectToOpen; } protected override void OnActivated() { base.OnActivated(); ObjectSpace.Committed += ObjectSpace_Committed; } private void ObjectSpace_Committed(object sender, EventArgs e) { if(ownerView == null || ownerView.IsDisposed) { return; } ownerView.ObjectSpace.ReloadObject(objectToOpen); if(ownerView is ListView) { ListView listView = (ListView)ownerView; if(listView.Editor is GridListEditor) { GridListEditor gridListEditor = ((GridListEditor)listView.Editor); //refresh all visible rows in a grid control gridListEditor.GridView.LayoutChanged(); } } if(ownerView is DetailView) { DetailView detailView = (DetailView)ownerView; //refresh a display text at property editors IEnumerable<IObjectPropertyEditor> objectPropertyEditors = detailView.Items.OfType<IObjectPropertyEditor>(); foreach(PropertyEditor objectPropertyEditor in objectPropertyEditors) { if(objectPropertyEditor.PropertyValue == objectToOpen) { objectPropertyEditor.Refresh(); } } IEnumerable<LookupPropertyEditor> lookupPropertiesEditors = detailView.Items.OfType<LookupPropertyEditor>(); foreach(LookupPropertyEditor lookupPropertyEditor in lookupPropertiesEditors) { if(lookupPropertyEditor.PropertyValue == objectToOpen) { lookupPropertyEditor.Refresh(); } } } } protected override void OnDeactivated() { base.OnDeactivated(); ObjectSpace.Committed -= ObjectSpace_Committed; } } public class RefreshViewFromRelatedObjectDetailViewController : ViewController { public RefreshViewFromRelatedObjectDetailViewController() : base() { } protected override void OnActivated() { base.OnActivated(); OpenObjectController openObjectController = Frame.GetController<OpenObjectController>(); if(openObjectController != null) { openObjectController.CustomOpenObject += OpenObjectController_CustomOpenObject; } } protected override void OnDeactivated() { OpenObjectController openObjectController = Frame.GetController<OpenObjectController>(); if(openObjectController != null) { openObjectController.CustomOpenObject -= OpenObjectController_CustomOpenObject; } base.OnDeactivated(); } private void OpenObjectController_CustomOpenObject(object sender, CustomOpenObjectEventArgs e) { e.InnerArgs.ShowViewParameters.Controllers.Add(new RefreshDataInOwnerObjectViewController(View, e.ObjectToOpen)); } } }

Thanks,
Nat.

    Show previous comments (9)

      Thanks, Uriah,

      That seems to do the trick. I'll keep an eye out on this. Really seems like this should just be the default behavior.

      DevExpress Support Team 7 years ago

        Thank you for the clarification. I added this code to the answer above so that others customers who will use this code will not experience the same issue.

          To be honest I never noticed this problem, until I read this ticket and tested it. This is the kind of detail we expect xaf to just work. I agree this should be the default behavior, but the provided solution works perfectly. Thanks.

          For those who already have a derived OpenObjectController, you can avoid the second controller altogether, by doing something like this:

          C#
          protected override void OnCustomOpenObject(CustomOpenObjectEventArgs e) { base.OnCustomOpenObject(e); e.InnerArgs.ShowViewParameters.Controllers.Add(new RefreshDataInOwnerObjectViewController(View, e.ObjectToOpen)); }

          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.