Ticket T709207
Visible to All Users
Duplicate

Custom Fields that change based on properties of a Business Object

created 6 years ago

Hi Support!

I have a requirement to have a business class, which will have dynamic/custom fields, but these custom fields will differ between different instances of the object. An example would be as follows:

I have a business class called "Equipment". This c lass has a property called "EquipmentType" which indicates what "type" of equipment it is e.g. a car, truck, hammer, drill etc. Depending on the EquipmentType, an instance of the Equipment object will have different custom fields. e.g. a car may have a field called "TopSpeed" whereas a truck may have field called "MaximumCapacity".

I have two questions for this scenario:

  1. How can I have a Detailed View dynamically show the custom fields relevant to the instance of the object? (I have thought the only way to really do this, would be to create a custom editor for this purpose, but wondering if there is a better way)

  2. How can I have these dynamic properties appear in the dashboard designer? I don't mind if ALL properties for all instances are shown in the dashboard designer, but wondering how I can do this. Using the Module "CustomizeTypesInfo override" I seem to only be able to statically add dynamic properties, however in this case, the dynamic properties are defined by the user (i.e. the Module CustomizeTypesInfo override does not seem to have access to the ObjectSpace to create the properties dynamically)

Thanks,

Jarrad

Answers approved by DevExpress Support

created 6 years ago

Hi Jarrad,

Yes, you can add additional properties to your business class in the CustomizeTypesInfo method. You don't need an ObjectSpace instance to do this. I also suggest you consider adding additional properties in the Model Editor. The Customize Business Object's Metadata article describes both of these approaches. Such additional properties will be available in the Dashboard Designer. If you don't see them, please provide me with a sample project to illustrate the issue.

I suggest you add all required properties to your business class. On a Detail View, you can show/hide some of them in a custom controller or via appearance rules.

    Show previous comments (4)
    Andrey K (DevExpress Support) 6 years ago

      Hello,

      To provide you with the most suitable solution we need more information about your scenario. In case you already have a set of properties the Equipment class can have - define all these properties in this class and then hide unneeded properties based on the EquipmentType property's value. Gosha described this approach in detail earlier.
      In case you wish to allow end-users to add arbitrary properties at runtime, refer to the Add a Custom Persistent Field in the Model Editor at Runtime and Add Custom Fields in Code articles that describe how to implement this functionality.
      With both these approaches, custom fields should be available in dashboards' designer.

      If these approaches don't meet your requirements, describe your scenario and ultimate goal from an end user's point of view and we will find the most suitable solution for you.

      Thanks,
      Andrey

        Hi Andrey,

        Thanks for the reply.

        The am sorry this isn't clear - I am having trouble explaining the problem other than from the example I gave.

        I am trying to build an application where the end-user can define their own properties for a business entity. In my example of "Equipment" the end user might define the property of "MaximumSpeed" or "MaximumCapacity". These properties are not calculated and would either be some text or a numeric value. But as the developer, we don't know what the properties are, because the end-user will define them at runtime.

        I have read "Add a Custom Persistent Field in the Model Editor at Runtime" (https://documentation.devexpress.com/eXpressAppFramework/113583/Concepts/Business-Model-Design/Types-Info-Subsystem/Customize-Business-Object-s-Metadata#2.2) article. However, I need the custom fields will not be applicable to EVERY instance of the business object (e.g. in my example, on Equipment of type "Car" would show the property of "MaximumSpeed"), therefore I need to control the visibility of the custom field in a detail view. I would like the end-user to have a simpler user interface than the model editor to achieve this. I just want the end-user to be able to enter a name of a property and maybe a data type (e.g. string or double), and then we programmatically add the fields to the BOModel. I would assume I would have these properties defined in the database (e.g. EquipmentTypeProperty from my example), and we could access them via an ObjectSpace to add them to the BOModel.

        So I then read the article Add Custom Fields in Code (https://documentation.devexpress.com/eXpressAppFramework/113583/Concepts/Business-Model-Design/Types-Info-Subsystem/Customize-Business-Object-s-Metadata#3) but I couldn't see a way that I could access the ObjectSpace.

        Does that make it any clearer? If not, I will try to draw some mockups to help explain.

        Thanks for your help.

        DevExpress Support Team 6 years ago

          Hi Jarrad,

          As for a simpler user interface and custom logic for these fields, you can implement fully custom solutions depending on your business requirements. We described more options in the How to define a business class at runtime or allow end-users to configure its members via the application UI? ticket. There are no ready XAF options and you will need to research it on your own.

          The CustomizeTypesInfo method is the correct place to add dynamic properties to a business class. To fetch property names from a database, create IObjectSpace manually as described in the Access XAF Application Data in a non-XAF Application article or use ADO.NET APIs as without XAF/XPO. Once you obtain property names, you can add writeable and calculated properties for each of them using the CreateMember API.

          To query other tables in your for calculated properties, consider using Free Joins. To get a single property value from a collection,  use aggregated functions ( Min, Max, Single). Consider the following example:

          C#
          public override void CustomizeTypesInfo(ITypesInfo typesInfo) { base.CustomizeTypesInfo(typesInfo); CalculatedPersistentAliasHelper.CustomizeTypesInfo(typesInfo); TypeInfo typeInfo = (TypeInfo)typesInfo.FindTypeInfo(typeof(Equipment)); XPObjectSpaceProvider osProvider = new XPObjectSpaceProvider(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString, null); IObjectSpace objectSpace = osProvider.CreateObjectSpace(); var additionalProperties = objectSpace.GetObjects<EquipmentTypeProperty>().Select(p => p.Name).Distinct(); foreach (var prop in additionalProperties) { // Create a writeable member. typeInfo.CreateMember(prop, typeof(double)); // Create a readonly member based on a criteria expression. typeInfo.CreateMember(prop, typeof(double), $"[<EquipmentTypePropertyValue>][^.Oid = Equipment.Oid && EquipmentTypeProperty.Name = '{prop}'].Min(Value)"); } typesInfo.RefreshInfo(typeof(Equipment)); }

          Please let me know if this works for you. We and the whole XAF community would also greatly appreciate it if you keep us informed of your final solutions and experience with them.

          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.