This blog provides code snippets that demonstrate how to use EC Expression with properties:
Expressions currently work with Primitive properties. They do not support Struct or Array type of properties.Below steps explain how to use Managed and Native EC Expression API’s with EC Property:
Sample EC Schema
Following is the EC Schema used to perform set/get EC Expression operations onto EC Properties:
<?xml version="1.0" encoding="utf-8"?> <ECSchema schemaName="PropertyTypes" nameSpacePrefix="pt" version="1.0" description="For testing properties" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.2.0"> <ECClass typeName="PropertiesClass" isDomainClass="True"> <ECProperty propertyName="StringProperty" typeName="string" readOnly="True"> <ECCustomAttributes> <CalculatedECPropertySpecification xmlns="Bentley_Standard_CustomAttributes.01.13"> <ECExpression>this.GetElement().ElementDescription</ECExpression> <FailureValue>Failed String Expression</FailureValue> <IsDefaultValueOnly>False</IsDefaultValueOnly> <RequiredSymbolSets> <string>System.Math</string> <string>System.Path</string> <string>System.String</string> <string>Items</string> <string>LookUp</string> </RequiredSymbolSets> <EnforceUnits>False</EnforceUnits> </CalculatedECPropertySpecification> </ECCustomAttributes> </ECProperty> </ECClass> </ECSchema>
API’s to work with EC Expression
Following are the APIs used to set EC Expression in item type property definition:
auto& dgnfile = *GetDgnModelP()->GetDgnFileP(); ItemTypeLibraryPtr lib = ItemTypeLibrary::Create(L"PropertyTypes", dgnfile); ItemTypeP itp1 = lib->AddItemType(L"PropertiesClass"); CustomPropertyP prop1 = itp1->AddProperty(L"StringProperty"); prop1->SetType(CustomProperty::Type::String); prop1->SetExpression(L"this.GetElement().ElementDescription"); lib->Write();
ItemTypeLibrary itLibrary = ItemTypeLibrary.Create("PropertyTypes", GetDgnFile()); ItemType itp = itLibrary.AddItemType ("PropertiesClass"); CustomProperty property = itp.AddProperty("StringProperty"); property.Type = CustomProperty.TypeKind.String; property.SetExpression(“this.GetElement().ElementDescription”); itLibrary.Write();
Function CreateItemTypeLibrary(sLibName As String) As ItemTypeLibrary Dim oItem As ItemType Dim oItemProp As ItemTypeProperty Dim oItemLibs As ItemTypeLibraries Dim sMessage As String 'Create ItemType Library Set oItemLibs = New ItemTypeLibraries Set CreateItemTypeLibrary = oItemLibs.CreateLib(sLibName, False) If CreateItemTypeLibrary Is Nothing Then MsgBox("ItemTypeLibrary with name TestLibrary already exist") Else 'Create first ItemType Set oItem = CreateItemTypeLibrary.AddItemType("FirstItemType") 'Calculated property Set oItemProp = oItem.AddProperty("StringProperty", ItemPropertyTypeString) Success = oItemProp.SetExpression("10+20", "Failed String Expression", sMessage) If Not sMessage = "" Then MsgBox(sMessage) End If CreateItemTypeLibrary.Write End If End Function
Following are the APIs used to set EC Expression Failure value in item type property definition:
auto& dgnfile = *GetDgnModelP()->GetDgnFileP(); ItemTypeLibraryPtr lib = ItemTypeLibrary::Create(L"PropertyTypes", dgnfile); ItemTypeP itp1 = lib->AddItemType(L"PropertiesClass"); CustomPropertyP prop1 = itp1->AddProperty(L"StringProperty"); prop1->SetType(CustomProperty::Type::String); prop1->SetExpression(L"this.GetElement().ElementDescription",L"Failed String Expression"); lib->Write();
ItemTypeLibrary itLibrary = ItemTypeLibrary.Create("PropertyTypes", GetDgnFile()); ItemType itp = itLibrary.AddItemType ("PropertiesClass"); CustomProperty property = itp.AddProperty("StringProperty"); property.Type = CustomProperty.TypeKind.String; property.SetExpression(“this.GetElement().ElementDescription”, "Failed String Expression"); itLibrary.Write();
Following are the APIs used to get EC Expression from item type property definition:
auto& dgnfile = *GetDgnModelP()->GetDgnFileP(); ItemTypeLibraryPtr lib = ItemTypeLibrary::Create(L"PropertyTypes", dgnfile); ItemTypeP itp1 = lib->AddItemType(L"PropertiesClass"); CustomPropertyP prop1 = itp1->AddProperty(L"StringProperty"); prop1->SetType(CustomProperty::Type::String); prop1->SetExpression(L"this.GetElement().ElementDescription"); lib->Write(); ECValue value; prop1->GetExpression(value); wprintf (L"Expression=", value.ToString().c_str());
ItemTypeLibrary itLibrary = ItemTypeLibrary.Create("PropertyTypes", GetDgnFile()); ItemType itp = itLibrary.AddItemType ("PropertiesClass"); CustomProperty property = itp.AddProperty("StringProperty"); property.Type = CustomProperty.TypeKind.String; property.SetExpression((“this.GetElement().ElementDescription”); itLibrary.Write(); Console.WriteLine("Expression=", property.Expression);
Set CreateItemTypeLibrary = oItemLibs.CreateLib(sLibName, False) Set oItem = CreateItemTypeLibrary.AddItemType("FirstItemType") Set oItemProp = oItem.AddProperty("StringProperty", ItemPropertyTypeString) Success = oItemProp.SetExpression("10+20", "Failed String Expression", sMessage) CreateItemTypeLibrary.Write Debug.Print "Expression= " & itemTypeProp.GetExpression & vbNewLine;
Following are the APIs used to get EC Expression Failure value from item type property definition:
auto& dgnfile = *GetDgnModelP()->GetDgnFileP(); ItemTypeLibraryPtr lib = ItemTypeLibrary::Create(L"PropertyTypes", dgnfile); ItemTypeP itp1 = lib->AddItemType(L"PropertiesClass"); CustomPropertyP prop1 = itp1->AddProperty(L"StringProperty"); prop1->SetType(CustomProperty::Type::String); prop1->SetExpression(L"this.GetElement().ElementDescription",L"Failed String Expression"); lib->Write(); ECValue value; prop1->GetExpressionFailureValue (value); wprintf (L"ExpressionFaluireValue=", value.ToString().c_str());
ItemTypeLibrary itLibrary = ItemTypeLibrary.Create("PropertyTypes", GetDgnFile()); ItemType itp = itLibrary.AddItemType ("PropertiesClass"); CustomProperty property = itp.AddProperty("StringProperty"); property.Type = CustomProperty.TypeKind.String; property.SetExpression("this.GetElement().ElementDescription", "Failed String Expression"); itLibrary.Write(); Console.WriteLine("Expression=", property.ExpressionFailureValue);
Set CreateItemTypeLibrary = oItemLibs.CreateLib(sLibName, False) Set oItem = CreateItemTypeLibrary.AddItemType("FirstItemType") Set oItemProp = oItem.AddProperty("StringProperty", ItemPropertyTypeString) Success = oItemProp.SetExpression("10+20", "Failed String Expression", sMessage) CreateItemTypeLibrary.Write failureValue = itemTypeProp.GetExpressionFailureValue Debug.Print "Calulated property failure value = " & failureValue & vbNewLine;
Following are the APIs used to verify input EC Expression is valid or not:
auto& dgnfile = *GetDgnModelP()->GetDgnFileP(); ItemTypeLibraryPtr lib = ItemTypeLibrary::Create(L"PropertyTypes", dgnfile); ItemTypeP itp1 = lib->AddItemType(L"PropertiesClass"); CustomPropertyP prop1 = itp1->AddProperty(L"StringProperty"); prop1->SetType(CustomProperty::Type::String); WCharCP message = L""; WCharCP expression = L"1**2"; if (prop1->IsValidExpression (expression, message)) prop1->SetExpression (expression, L"Failed String Expression"); else wprintf (message); lib->Write();
ItemTypeLibrary itLibrary = ItemTypeLibrary.Create("PropertyTypes", GetDgnFile()); ItemType itp = itLibrary.AddItemType ("PropertiesClass"); CustomProperty property = itp.AddProperty("StringProperty"); property.Type = CustomProperty.TypeKind.String; String expression = "1**2; String message = ""; if (property1.IsValidExpression(expression,message)) property1.SetExpression(expression); else Console.WriteLine(message); itLibrary.Write();
Set CreateItemTypeLibrary = oItemLibs.CreateLib(sLibName, False) Set oItem = CreateItemTypeLibrary.AddItemType("FirstItemType") Set oItemProp = oItem.AddProperty("StringProperty", ItemPropertyTypeString) Success = oItemProp.SetExpression("10**20", "Failed String Expression", sMessage) If Not sMessage = "" Then MsgBox(sMessage) End If CreateItemTypeLibrary.Write
Hi Jon,
Here is the link, where you can find list of EC expressions supported(.pdf file):
https://communities.bentley.com/products/microstation/b/microstation_blog/posts/ec-expressions-in-item-types---new-in-microstation-connect-edition-update-12
Related to your second question:
If you want to use expression in Item type, then there is no need to create schema separately and import it. Item type API does it internally.
Here, ItemtypeLibrary name internally referred as schema name and Itemtype name as ECClass name.
property.SetExpression(“this.GetElement().ElementDescription”);
Where are those Expressions documented?
ECSchema schemaName="PropertyTypes"
Where is the XML file that defines that schema? I found another XML file that contains ECSchema schemaName="Bentley_Standard_CustomAttributes", which defines ECClass typeName="CalculatedECPropertySpecification".