//Link to a Property on this element ElementId elemIdLink = ElementIDLink; ElementHandle elemLink(elemIdLink, pActiveModel); if (!elemLink.IsValid()) { return false; } ElementECClassInfo ecClassInfo2; DgnECManagerR ecManager = DgnECManager::GetManager(); ecManager.FindECClassesOnElement(elemLink.GetElementRef(), ecClassInfo2); //how would i loop ecClassInfo2 to find the item type i want? //need to figure out how to get classes ecManager.FindInstanceOnElement(elemLink, ecClass2); //this is wrong
trying to figure out how to do this..
I need to get the ec instance of an item type instance that is attached to an element.
I need this to add a text field to a text element via TextField::CreateForElement.
im struggling on how to do that...
Hi John,
is there any specific reason, why to use generic "EC approach" when you want to work specifically with ItemType data?
I recall it has been discussed several times, I found e.g. this discussion (but not sure whether the code is working).
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Answer Verified By: John Drsek
no reason, just thought that's the way I needed..
I looked briefly at the post (about to leave for the day) how would I take that DgnECInstancePtr and get a DgnElementECInstancePtr from it to use in the
TextField::CreateForElement method?
Ill look more into it tomorrow
thanks
JD
John Drsek said:I need to get the ec instance of an item type instance that is attached to an element
This article about EC Queries may help. It distils tips that Paul Connelly and others have given over the years. You need to create a scope and a query before calling DgnECManager::FindInstances.
DgnECManager::FindInstances
Regards, Jon Summers LA Solutions
Thanks Jan and Jon, wouldn't have gotten this without your help, much appreciated.
I ended up going the way the post Jan linked to since it was simpler and to do the EC query way that Jon posted I would need to get the item type anyways to get the internal names.
but Jon that web link is awesome, I did try it out and I will probably be using it in the future. it did show me the GetAsElementInstance method that I needed.
here is my code for anyone its a method that takes the id to a text element and a id to the element that contains the item type instance you want to create a field for. ill probably be adding a 3rd parameter for the property name you cant the field to be linked to. but it will add a field linked to a property of the item type instance to the end of the text element.
bool AddField(__int64 ElementIDText, __int64 ElementIDLink) { DgnModelP pActiveModel = ISessionMgr::GetActiveDgnModelP(); DgnFileP activeDgnFile = ISessionMgr::GetActiveDgnFile(); //Text Element to add field to ElementId elemIdText = ElementIDText; //text element ElementHandle elemText(elemIdText, pActiveModel); //text element if (!elemText.IsValid()) { return false; } //Link to Property on this element ElementId elemIdLink = ElementIDLink; ElementHandle elemLink(elemIdLink, pActiveModel); //text element if (!elemLink.IsValid()) { return false; } EditElementHandle eehLink(elemIdLink, pActiveModel); //get text block (should only be one text part) TextBlockPtr pTextBlock = TextHandlerBase::GetFirstTextPartValue(elemText); //get Inst of link element itemtype ItemTypeLibraryPtr newLibrary = ItemTypeLibrary::FindByName(L"OHDOT_Linkers", *activeDgnFile); if (newLibrary.IsValid()) { ItemTypeP itemType = newLibrary->GetItemTypeByName(L"TextFieldLinker"); //nullptr if not found if (itemType) { CustomItemHost host(eehLink); DgnECInstancePtr itemInstance = host.GetCustomItem(newLibrary->GetName(), itemType->GetName()); if (itemInstance.IsValid()) { DgnElementECInstanceP elementItemInstance = itemInstance->GetAsElementInstance(); TextFieldPtr pField = TextField::CreateForElement(*elementItemInstance, L"Values[0].ModelName", nullptr, *pActiveModel); if (pField == NULL) { return false; } pTextBlock->AppendField(*pField); //add field to text block //replace old textblock with new one EditElementHandle eeh(elemIdText, pActiveModel); ITextEditP et = eeh.GetITextEdit(); T_ITextPartIdPtrVector partIds; et->GetTextPartIds(eeh, *ITextQueryOptions::CreateDefault(), partIds); et->ReplaceTextPart(eeh, *partIds[0], *pTextBlock); //replace element in model eeh.ReplaceInModel(elemText.GetElementRef()); return true; } else { return false; } } else { return false; } } else { return false; }
John Drsek said:I ended up going the way the post Jan linked to since it was simpler
probably (nearly) always, when you need to access ItemTypes data and not other type of EC data (e.g. based on custom schema created in Bentley Class Editor or EC data created by other applications), to use ItemTypes API is simpler and quicker.
Although ItemTypes data are EC data, specialized API hides some implementation details and automates some steps, so it's not necessary to know all details how EC schemas work and how ItemTypes are implemented as particular EC schema.
And of course, thanks for your code! :-)