Ticket T246753
Visible to All Users
Duplicate

Actions & DataViewMode: Converting eventArgs / SelectedObjects

created 10 years ago

Hello DevExpress Team,

I have a question regarding list views in dataview mode and actions.

Background:
To make sure that our ViewControllers work correctly both in DataView mode and none-DataView mode we created our own action class (derived from SimpleAction).
In its overwritten RaiseExecute method we check the passed (SimpleActionExecuteEventArgs)eventArgs object
whether its CurrentObject/SelectedObjects properties contain objects of type XafDataViewRecord.
If this is the case we want to replace them with the 'real' objects (queried by ObjectSpace.GetObjects).

C#
protected override void RaiseExecute(ActionBaseEventArgs eventArgs) { var simpleActionEventArgs = GetRealEventArgs(eventArgs, this); ... base.RaiseExecute(simpleActionEventArgs ?? eventArgs); }

Currently we replace the eventargs with a new instance that contains the real objects:

C#
public static ActionBaseEventArgs GetRealEventArgs(ActionBaseEventArgs eventArgs, ActionBase action) { var simpleActionEventArgs = (SimpleActionExecuteEventArgs)eventArgs; ... var typeInfo = XafTypesInfo.CastTypeToTypeInfo(simpleActionEventArgs.CurrentObject.GetType()); if (!typeInfo.Implements<XafDataViewRecord>() ) return null; var realObjects = GetRealObjectsInternal(...); // Get corresponding objects via ObjectSpace.GetObjects var realCurrentObject = GetCurrentObjectInternal(...); return new SimpleActionExecuteEventArgs(action, new OurSelectionContext(realCurrentObject, realObjects)); }

-> Drawback: Querying of the real objects always takes place when an action is executed, no matter if anybody actually needs them.

So my question is:
Would it be possible to make the SimpleActionExecuteEventArgs Properties CurrentObject and SelectedObjects virtual?
Then we could derive our own class from SimpleActionExecuteEventArgs and query the real objects in these getter functions if needed.
So the queries only would take place if someone accesses SelectedObjects (or CurrentObject).

Or do you have any other suggestions for this problem?

Thanks for your help,

Witold

Answers approved by DevExpress Support

created 10 years ago

Hello Witold.

Thank you for your suggestion. In fact, additional tests for the XafDataViewRecord type are not required. You can always and unconditionally call the ObjectSpace.GetObject method in your code to obtain a real object in the required object space. It automatically loads an object if a XafDataViewRecord instance or an object from another object space is passed in the argument.

    Comments (3)

      Hello Michael,
      Thank you for that information! It will make 1-2 of our methods obsolet.
      However we also use the result of the testing for the XafDataViewRecord type to determine if we should subscribe to
      the ObjectSpace.Committed event:
      var simpleActionEventArgs = GetRealEventArgs(eventArgs, this);
      if (simpleActionEventArgs != null)
         (Controller as ViewController).View.ObjectSpace.Committed += ObjectSpace_Committed;

      void ObjectSpace_Committed(object sender, EventArgs e)
      {
           (Controller as ViewController).View.Refresh();
      }
      Without this event handling the list view did not automatically update in dataview mode if an action had an effect on the number of items in the list.
      To get the eventArgs SelectedObjects collection as real objects we do the following:
      public static IList GetRealObjectsInternal(IObjectSpace objectSpace, IEnumerable<XafDataViewRecord> viewRecords)
      {
          return GetObjectsByOid(objectSpace, viewRecords.First().ObjectType, viewRecords.Select(r => (Guid)r["Oid"]));
      }
      public static IList GetObjectsByOid(IObjectSpace objectSpace, Type type, IEnumerable<Guid> oids)
      {
           var criteria = new InOperator("Oid", oids);
           return objectSpace.GetObjects(type, criteria);
      }
      The only alternative would be to get each single object in the SelectedObjects collection via ObjectSpace.GetObject, do i understand it correctly?
      Or is there another way?
      Thanks,
      Witold

      DevExpress Support Team 10 years ago

        Thank you for your reply.

        Indeed, it is necessary to manually refresh the list view after modifying objects when the view is in DataView mode, because objects are not loaded in this mode. Instead of checking the object type to match XafDataViewRecord, you could test the DataAccessMode property of ListView.CollectionSource and use the Reload method of the collection source instead of refreshing the entire object space.

        As for GetRealObjectsInternal, the more type-agnostic version of it is the following:

        C#
        public static IList GetRealObjectsInternal(IObjectSpace objectSpace, Type type, IEnumerable records) { var keys = new ArrayList(); foreach (var r in records) { keys.Add(objectSpace.GetKeyValue(r)); } return objectSpace.GetObjects(type, new InOperator(objectSpace.GetKeyPropertyName(type), keys)); }

        or you can reload each object separately using objectSpace.GetObject.

          Thank you for these explanations!

          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.