Ticket T584572
Visible to All Users

How to access real persistent objects through the SelectedObjects and CurrentObject properties of View and Action's event arguments when DataAccessMode = DataView or InstantFeedback

created 7 years ago

Hello DevExpress team!

I would like to ask you whether is is possible to fill CurrentObject and SelectedObjects in any event before an action is executed. This question was already asked and answered before , but I would like to make a step further. Since there is a lot of code in our ViewControllers depending on CurrentObject or SelectedObjects property, I would like to make sure that there is no other method than writing a method and replacing the occurrences of SelectedObjects and CurrentObject by my methods below instead of filling CurrentObject or SelectedObjects properties.

My methods are:

C#
public static IEnumerable<object> GetSelectedObjects(this View view) { List<object> result = new List<object>(view.SelectedObjects.Count); foreach (object obj in view.SelectedObjects) { result.Add(view.EnsureBusinessObject(obj, true)); } return result; } public static object GetCurrentObject(this View view) { return view.EnsureBusinessObject(view.CurrentObject, true); } public static object EnsureBusinessObject(this View view, object obj, bool throwExceptionIfObjectByDataViewRecordCantBeFound) { object result = null; if (obj != null) { if (obj is XpoDataViewRecord) { Type objectType = ((XpoDataViewRecord)obj).ObjectType; XPClassInfo classInfo; if (view != null && objectType != null && view.GetSession() != null) { classInfo = view.GetSession().GetClassInfo(objectType); } else { classInfo = null; } object persistentObject = null; string keyPropertyName = null; object keyPropertyValue = null; if (classInfo != null) { keyPropertyName = classInfo.KeyProperty.Name; keyPropertyValue = ((XpoDataViewRecord)obj)[classInfo.KeyProperty.Name]; if (keyPropertyValue != null) { persistentObject = view.ObjectSpace.GetObjectByKey(view.ObjectTypeInfo.Type, keyPropertyValue); } } if (persistentObject != null) { result = persistentObject; } else if (throwExceptionIfObjectByDataViewRecordCantBeFound) { string exceptionMessage = "Record not found."; throw new InvalidOperationException(exceptionMessage); } } else { result = obj; } } return result; }

Answers approved by DevExpress Support

created 7 years ago (modified 7 years ago)

Hello Svatopluk,

The View.CurrentObject and View.SelectedObjects properties return XafDataViewRecord objects instead of original business objects when the View operates in the DataView mode (and XafInstantFeedbackRecord - in InstantFeedback mode). To get the real object, use the View.ObjectSpace.GetObject(obj)  method.

To apply this solution, consider one of the two strategies:
1. Local
Modify your code in each required ViewController, e.g. in the Action's Execute event handler, as per the Task-Based Help > How to: Access Objects Selected in the Current View  article.

2. Global
Make a ListView class descendant and override its SelectedObjects and CurrentObject properties as shown below. However, the use of this approach for each ListView with DataView or InstantFeedback may prevent you from getting all the benefits of these modes, because separate SQL queries will be made to load persistent objects. So, I suggest you use this approach carefully or not use it at all. For instance, take a look at the Client and Server modes.

C#
using System; using System.Collections; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Win; public class MainDemoWinApplication : WinApplication { //..... protected override void OnListViewCreating(ListViewCreatingEventArgs args) { base.OnListViewCreating(args); if((args.View == null) && (args.CollectionSource != null) && (args.CollectionSource.DataAccessMode == CollectionSourceDataAccessMode.InstantFeedback || args.CollectionSource.DataAccessMode == CollectionSourceDataAccessMode.DataView) && !String.IsNullOrEmpty(args.ViewID)) { DevExpress.ExpressApp.Model.IModelView modelView = FindModelView(args.ViewID); if(modelView == null) { throw new Exception(DevExpress.ExpressApp.Localization.SystemExceptionLocalizer.GetExceptionMessage(DevExpress.ExpressApp.Localization.ExceptionId.NodeWasNotFound, args.ViewID)); } DevExpress.ExpressApp.Model.IModelListView modelListView = modelView as DevExpress.ExpressApp.Model.IModelListView; if(modelListView != null) { args.View = new MyListView(modelListView, args.CollectionSource, this, args.IsRoot); } } } } public class MyListView : ListView { public MyListView(DevExpress.ExpressApp.Model.IModelListView modelListView, CollectionSourceBase collectionSource, XafApplication application, bool isRoot) : base(modelListView, collectionSource, application, isRoot) { } public override IList SelectedObjects { get { ArrayList selectedObjects = new ArrayList(); foreach(object obj in base.SelectedObjects) { selectedObjects.Add(ObjectSpace.GetObject(obj)); } return selectedObjects; } } public override object CurrentObject { get { return this.ObjectSpace.GetObject(base.CurrentObject); } set { base.CurrentObject = value; } } }

See Also:
Concepts > UI Construction > Views > List View Data Access Modes Overview

    Comments (2)
    SU SU
    Svatopluk Ulicny 7 years ago

      Thank you for your answer. Have a nice day!

      Dennis Garavsky (DevExpress) 7 years ago

        You're always welcome!

        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.