KB Article T324232
Visible to All Users

How to hide or filter out certain types from the drop-down editor for the System.Type properties

Description:


Answer:
Type properties are defined in code and represented in the application UI for different platforms as described in the eXpressApp Framework > Concepts > Business Model Design > Data Types Supported by built-in Editors > Type Properties documentation article. Thus, there are three possible ways of accomplishing this task, which apply at different application layers:

1. Data model level
Since the System.Type properties are usually declared using System.ComponentModel.TypeConverterAttribute that provides a TypeConverter class for setting a list of default values or default choice of types shown in the editor, you can provide a custom TypeConverter that contains only required types. A custom TypeConverter class can either be implemented from scratch or inherited from built-in XAF ones like LocalizedClassInfoTypeConverter or ClassInfoTypeConverter.
If you own the source code of the target System.Type property, you can change its declaration directly in the code of your business class. Otherwise (e.g., you want to customize the behavior of a class in a third-party assembly), you can remove the default TypeConverterAttribute and replace it with a required one at runtime as per eXpressApp Framework > Concepts > Business Model Design > Types Info Subsystem > Customize Business Object's Metadata. To find the exact type of TypeConverter used in such a class, refer to its source code. The location of DevExpress source code is shown in the KA18677: Where can I get demo source code folder, installed assemblies, or source code on machines with different OS versions article. The following source code illustrates this approach in action for a scenario when a list of types shown for the TargetType editor of the security type permission record in the UI is filtered:

C#
using System; using System.Linq; using System.ComponentModel; using DevExpress.ExpressApp; using MainDemo.Module.Reports; using DevExpress.ExpressApp.DC; using DevExpress.ExpressApp.Xpo; using System.Collections.Generic; using DevExpress.ExpressApp.Updating; using DevExpress.ExpressApp.ReportsV2; using MainDemo.Module.BusinessObjects; using DevExpress.ExpressApp.Security.Strategy; namespace MainDemo.Module { public sealed partial class MainDemoModule : ModuleBase { public MainDemoModule() { InitializeComponent(); } public override void CustomizeTypesInfo(ITypesInfo typesInfo) { base.CustomizeTypesInfo(typesInfo); CalculatedPersistentAliasHelper.CustomizeTypesInfo(typesInfo); SecurityTargetTypeConverterEx.TypesToBeExcluded.Add(typeof(MainDemo.Module.BusinessObjects.Contact)); SecurityTargetTypeConverterEx.TypesToBeExcluded.Add(typeof(DevExpress.Persistent.BaseImpl.Country)); SecurityTargetTypeConverterEx.CustomizeTypesInfo(typesInfo); } } public class SecurityTargetTypeConverterEx: SecurityTargetTypeConverter { public static readonly IList<Type> TypesToBeExcluded = new List<Type>(); public override List<Type> GetSourceCollection(ITypeDescriptorContext context) { List<Type> result = base.GetSourceCollection(context); foreach(Type item in TypesToBeExcluded) { result.Remove(item); } return result; } public static void CustomizeTypesInfo(ITypesInfo typesInfo) { ITypeInfo typeInfo = typesInfo.FindTypeInfo(typeof(PermissionPolicyTypePermissionObject)); if(typeInfo != null) { BaseInfo memberBaseInfo = typeInfo.Members.First(p => p.Name == "TargetType") as BaseInfo; if(memberBaseInfo != null) { TypeConverterAttribute typeConverterAttribute = memberBaseInfo.FindAttribute<TypeConverterAttribute>(); if(typeConverterAttribute != null) { memberBaseInfo.RemoveAttribute(typeConverterAttribute); } memberBaseInfo.AddAttribute(new TypeConverterAttribute(typeof(SecurityTargetTypeConverterEx))); } } } } }
Visual Basic
Imports System Imports System.Linq Imports System.ComponentModel Imports DevExpress.ExpressApp Imports MainDemo.[Module].Reports Imports DevExpress.ExpressApp.DC Imports DevExpress.ExpressApp.Xpo Imports System.Collections.Generic Imports DevExpress.ExpressApp.Updating Imports DevExpress.ExpressApp.ReportsV2 Imports MainDemo.[Module].BusinessObjects Imports DevExpress.ExpressApp.Security.Strategy Namespace MainDemo.[Module] Public NotInheritable Partial Class MainDemoModule Inherits ModuleBase Public Sub New() InitializeComponent() End Sub Public Overrides Sub CustomizeTypesInfo(ByVal typesInfo As ITypesInfo) MyBase.CustomizeTypesInfo(typesInfo) CalculatedPersistentAliasHelper.CustomizeTypesInfo(typesInfo) SecurityTargetTypeConverterEx.TypesToBeExcluded.Add(GetType(MainDemo.[Module].BusinessObjects.Contact)) SecurityTargetTypeConverterEx.TypesToBeExcluded.Add(GetType(DevExpress.Persistent.BaseImpl.Country)) SecurityTargetTypeConverterEx.CustomizeTypesInfo(typesInfo) End Sub End Class Public Class SecurityTargetTypeConverterEx Inherits SecurityTargetTypeConverter Public Shared ReadOnly TypesToBeExcluded As IList(Of Type) = New List(Of Type)() Public Overrides Function GetSourceCollection(ByVal context As ITypeDescriptorContext) As List(Of Type) Dim result As List(Of Type) = MyBase.GetSourceCollection(context) For Each item As Type In TypesToBeExcluded result.Remove(item) Next Return result End Function Public Shared Sub CustomizeTypesInfo(ByVal typesInfo As ITypesInfo) Dim typeInfo As ITypeInfo = typesInfo.FindTypeInfo(GetType(PermissionPolicyTypePermissionObject)) If typeInfo IsNot Nothing Then Dim memberBaseInfo As BaseInfo = TryCast(typeInfo.Members.First(Function(p) p.Name = "TargetType"), BaseInfo) If memberBaseInfo IsNot Nothing Then Dim typeConverterAttribute As TypeConverterAttribute = memberBaseInfo.FindAttribute(Of TypeConverterAttribute)() If typeConverterAttribute IsNot Nothing Then memberBaseInfo.RemoveAttribute(typeConverterAttribute) End If memberBaseInfo.AddAttribute(New TypeConverterAttribute(GetType(SecurityTargetTypeConverterEx))) End If End If End Sub End Class End Namespace

Note: this approach allows you to write platform-agnostic logic only once. Also, in certain scenarios, you can use other specific approaches: SecurityStrategy.AdditionalSecuredTypes to add additional types in the current sample. In reporting and Pivot Chart analysis it is possible to decorate a business type with VisibleInReportsAttribute or manage the IModelClassReportsVisibility.IsVisibleInReports property in the Model Editor for that purpose.

2. UI PropertyEditor level
Since the System.Type properties are represented by the TypePropertyEditor, VisibleInReportsTypePropertyEditor classes for WinForms and ASPxTypePropertyEditor, ASPxVisibleInReportsTypePropertyEditor classes for ASP.NET in the XAF framework to build the resultant application UI, you can create descendants of these classes and override their virtual IsSuitableType method, which represents a predicate called for each checked type item before adding it into the editor control.
Refer to the eXpressApp Framework > Concepts > UI Construction > View Items > Implement Custom Property Editors  article and see some pseudo-code at Q337620 for more implementation details.
Note: this approach requires you to write the same logic for each descendant, but you can write it only once in a separate method and then call it twice from two descendants of the standard PropertyEditor class for each platform without knowing details of control implementation for each platform.

3. UI control level
Since the System.Type properties are represented by ImageComboBoxEdit for WinForms and ASPxComboBox for ASP.NET in the resultant application UI, you can access these controls and customize their items directly in code of your ViewControllers. Refer to the Access Editor Settings  article for more implementation details.
Note: this approach requires writing platform-dependent code. Despite its flexibility, it requires knowledge of each platform and their controls' low level implementation details as well as additional or different code for ListView/DetailView and other standard scenarios.

Comments (2)
SG SG
Sargis Gyulbaryan 9 years ago

    Hi,
    In code of approach #1 first removed the old TypeConverter attribute then added the new one. It is ok but pay attention about the problem of adding back of removed attribute that is described in  https://www.devexpress.com/Support/Center/Question/Details/T310890 ticket and fixed just in v2015 vol 2.5 of product.

    Dennis Garavsky (DevExpress) 9 years ago

      Thanks for your helpful note, Sargis

      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.