My code creates a text field associated with an Item instance. The text field is part of a cell.
If I modify an Item property, the text field doesn't update right away. It redraws itself eventually after I perform some user action. I haven't figured out exactly what 'user action' triggers the redraw.
What do I need to do programmatically to trigger the redraw of a text field? If I redraw the cell that contains the text field nothing happens.
Hi Jon,
Do you have a small code snip of how you are modifying the item property? This may help me identify what may be missing/needed,
Thank you,Bob
Robert Hook said:Do you have a small code snip?
/////////////////////////////////////////////////////////////////////// UInt32 ElementItemUpdater::Apply (Bentley::DgnPlatform::ElementId const& id, DgnModelRefP modelRef) const { UInt32 nAffected { 0 }; EditElementHandle eeh (id, modelRef); DgnECInstancePtr instance; if (ItemTypes::Attach (libName_.c_str (), itemTypeName_.c_str (), instance, eeh)) { nAffected = UpdateProperties (instance); } return nAffected; } /////////////////////////////////////////////////////////////////////// UInt32 ElementItemUpdater::UpdateProperties (DgnECInstancePtr& instance) const { UInt32 nItems { 0 }; if (instance.IsValid ()) { if (g_itemData.SetInstanceData (instance)) { instance->WriteChanges (); ++nItems; } } return nItems; } /////////////////////////////////////////////////////////////////////// bool ItemData::SetInstanceData (DgnECInstancePtr& instance) const { if (IsElemProp ()) return false; const bool& HasArrayIndex { true }; ECObjectsStatus status { instance->SetValueAsString (Name ().c_str (), ToString ().c_str (), !HasArrayIndex, 0) }; const bool rc { (ECOBJECTS_STATUS_Success == status) }; return rc; } /////////////////////////////////////////////////////////////////////// bool ItemTypes::Attach (WCharCP libName, WCharCP itemTypeName, DgnECInstancePtr& instance, EditElementHandleR eeh) { bool rc { false }; ItemTypeLibraryPtr lib = ItemTypeLibrary::FindByName (libName, *Utilities::GetActiveDgnFile ()); if (lib.IsValid ()) { CustomItemHost itemHost (eeh, !ScheduleItems_); DgnECInstancePtr pExisting = itemHost.GetCustomItem (libName, itemTypeName); if (pExisting.IsValid ()) { instance = pExisting; rc = instance.IsValid (); } else { // Attach this Item Type to the host element ItemTypeCP itemType = lib->GetItemTypeByName (itemTypeName); if (nullptr != itemType) { instance = itemHost.ApplyCustomItem (*itemType); rc = instance.IsValid (); } } } else { CMessageTracer moan (L"ItemTypes::Attach ItemTypeLibraryPtr not valid for lib "); moan.Quote (libName); moan.Advisory (); } return rc; }
Regards, Jon Summers LA Solutions
Robert Hook said: By chance do you also call: lib->Write()
No: what purpose would that serve (not that I'm unwilling to try it)?
The fact is that the Item properties are updated — it's just that they are not reflected in the UI. Nor does the text field associated with each property become updated.
This may be connected with another problem I reported where text fields that are components of a cell don't get updated reliably.
im having the same problem.
did you ever find a solution?
im thinking about going through and finding the text elements and redrawing them..
or trying the key in field update all via code...
John Drsek said:did you ever find a solution?
No. I think that the issue is buried deep in the bowels of EC Schema implementation in MicroStation. The system should notice that something changed, and that change should be propagated to places that use it (such as a text field that references an Item instance). It's just that it's not propagated — in human terms — immediately.
John Drsek said:I'm thinking about going through and finding the text elements and redrawing them
The text element hasn't changed. The text field in that text element hasn't changed. It's the data that's displayed by that text field that has changed.
My guess is that some event has to be triggered. However, AFAIK that event trigger is not exposed by the API.
https://communities.bentley.com/products/programming/microstation_programming/f/microstation-programming---forum/176790/connect-c-proper-use-of-dgnplatform-textfield-createplaceholderforcell/512032#512032
TextFields are driven by dependency relationships; dependency callbacks must be manually triggered (typically this occurs at transaction (undo/redo) boundaries e.g. when a tool exits etc); you can trigger them via DependencyManager::ProcessAffected().
Paul Connelly said:you can trigger them via DependencyManager::ProcessAffected().
I have text fields in text elements that are components of a cell. Each text field is assigned an Item instance property value. When the Item instance data are updated, the text fields do not immediately show the new values.
The text fields eventually update when user performs some action. It's not clear what action triggers the update.
Calling DependencyManager::ProcessAffected() in the tool after the Item instance properties have been updated makes no perceptible difference (nor does it appear to do any harm).
DependencyManager::ProcessAffected()
You don't need to see my code to reproduce this: it happens in plain old MicroStation...
Jon,
I get the same thing.
DependencyManager.ProcessAffected() does not update the fields within the text elements within a cell for me either.
this post was 6 months ago. I feel like this will be a very common problem. we need a fix/solution for this, as manually opening all the files is not a acceptable workaround.
another update on this.
I trying adding the following keyin after I made all the changes to the item type properties.
Bentley.MstnPlatformNET.Session.Instance.Keyin("field update all");
So here is what I'm consistently getting.
if I don't have the keyin to update all fields then none of the text elements that have fields linked to the item type properties get updated (unless its the active file)
if I put they key in in, only some of the text elements get updated but not all of them...very strange
but once the file is opened all the text elements get updated.
Paul
there appears to be a bug with the DependencyManager.ProcessAffected() method. It does not work if the text elements that contain the fields associated with a item type property are within a cell.
So if I drop the cell and then run my code to update item type properties, the ProcessAffected() method works..but obviously I don't want to drop the cell.
I submitted a service request on this. hoping this one can get a higher priority as item types are starting to be used everywhere.
currently the work around is I have to make the file active (open in not the background) and that not only makes the process a lot longer run time but I cant even open the file using the .net sdk since the ability is not there. I have to switch to interop just do that that...which is another enhancement that's filed..see community post here..hopefully that one can get pushed along as well... https://communities.bentley.com/products/programming/microstation_programming/f/microstation-programming---forum/177303/connect-c-switch-activedgnfile
EDIT:
I say above I cant activate a file with .net which was incorrect, I should have said I cant activate a model with the .net sdk.
John Drsek said:I cant even open the file using the .net sdk since the ability is not there
Off topic: please start a new thread with that question? (the answer, I think, is Session.Instance.NewDesignFile (fileName);)
Session.Instance.NewDesignFile (fileName);
Bob Hook provided that suggestion in this thread (in which you participated).
sorry Jon,
it wasn't a question .just statement.. and I meant to say I cant activate the model with .net… which would be needed for the work around...which is why its relevance.