I worked to change the code in MDL to C# for changing the value of Weight property of the element.
MDL (Original Code)
if (elemDescr == NULL) return; //--- traverse through descriptor ------------------------------ do { // If have a header, call us recursively if (elemDescr->h.isHeader) ApplyWeightSymbology(elemDescr->h.firstElem, weight); // Access next descriptor in chain mdlElement_getSymbology(NULL, NULL, &style, &elemDescr->el); if (style != 4) mdlElement_setSymbology(&elemDescr->el, NULL, &weight, NULL); elemDescr = elemDescr->h.next; } while (elemDescr);
C# implementation of above code
private void ApplyWeightSymbology(Element element, uint weight) { ChildElementCollection childElements = element.GetChildren(); foreach(Element childElement in childElements) { ElementPropertiesGetter propertiesGetter = new ElementPropertiesGetter(childElement); int styleId = propertiesGetter.LineStyleId; if(styleId != 4) { ElementPropertiesSetter propertiesSetter = new ElementPropertiesSetter(); propertiesSetter.SetWeight(weight); propertiesSetter.Apply(childElement); //childElement.AddToModel(); } } /*//--- If no descriptor, return if (elemDescr == NULL) return; //--- traverse through descriptor ------------------------------ do { // If have a header, call us recursively if (elemDescr->h.isHeader) ApplyWeightSymbology(elemDescr->h.firstElem, weight); // Access next descriptor in chain mdlElement_getSymbology(NULL, NULL, &style, &elemDescr->el); if (style != 4) mdlElement_setSymbology(&elemDescr->el, NULL, &weight, NULL); elemDescr = elemDescr->h.next; } while (elemDescr);*/ }
However this C# code does not changes the value of the Weight property, and does not generates any error either.
Regards,
Varsha
Hi Varsha,
Varsha Reddy said:However this C# code does not changes the value of the Weight property, and does not generates any error either.
I see several issues in your code:
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Jan Šlegr said:You commented out .AddToModel() method, so the change is not written back to DGN file.
childElement.AddToModel(); // <= Is incorrect regardless, you'd want to "replace" not "add" the outermost complex header.
.AddToModel actually writes back the element as well and distorts the cell element, however Apply should ensure the edit by the support document but that does not happen and .ReplaceToModel (Element replace) actually replaces the element with the current one.
public bool Apply(Element editElement)
I am currently looking at EditElementProperties
public static bool EditElementProperties (Element editElement, EditProperties editObject) in PropertyContext class
PropertyContext.EditElementProperties(Element editElement, EditProperties editObject)
but EditProperties is an abstract class need to inherit and override its methods. Any experience of this.
Tried something like this, considering the nested cell elements but no change in the properties.
private void ApplyWeightSymbology(Element element, uint weight) { IEnumerator<Element> childElements = element.GetChildren().GetEnumerator(); if (!childElements.MoveNext()) return; do { Element currentElement = childElements.Current; if (currentElement is CellHeaderElement) { ApplyWeightSymbology(currentElement, weight); continue; } ElementPropertiesGetter propertiesGetter = new ElementPropertiesGetter(currentElement); int styleId = propertiesGetter.LineStyleId; if (styleId != 4) { //EditProperties properties = null; //PropertyContext.EditElementProperties(currentElement, properties); ElementPropertiesSetter propertiesSetter = new ElementPropertiesSetter(); propertiesSetter.SetWeight(weight); propertiesSetter.Apply(currentElement); //currentElement.AddToModel(); } } while (childElements.MoveNext()); }
You need to rewrite the outermost header of the cell or complex element after making the modifications. propertiesSetter.Apply() modifies the current child element but doesn't persist the change.
propertiesSetter.Apply()
Regards, Jon Summers LA Solutions
Varsha Reddy said:ElementPropertiesSetter.Apply should ensure the edit by the support document but that does not happen
ElementPropertiesSetter.Apply
You've misunderstood the admittedly terse documentation. That method edits an Element but doesn't rewrite it. Use this idiom to rewrite an Element...
Element
void RewriteElementExample (Element elToModify) { DgnModel model = Session.Instance.GetActiveDgnModel(); Element original = model.FindElementById (elToModify.ElementId); ... do some work with elToModify elToModify.ReplaceInModel (original); }
Hi Jon,
Upon the suggested, the code worked as follows for me, when I made the changes directly on the element.
uint WEIGHT_ZERO = 0, WEIGHT_THREE = 3; uint sweight = 1000; int materialByOther = 0; IntPtr elementRef = element.GetNativeElementRef(); Element originalelement = Element.GetFromElementRef(elementRef); ElementPropertiesGetter propertiesGetter = new ElementPropertiesGetter(element); LevelId levelId = propertiesGetter.Level; LevelCache cache = Session.Instance.GetActiveDgnModel().GetLevelCache(); string name = cache.GetLevel(levelId).DisplayName; if (string.Equals(Global.Properties.MATERIAL_BY_OTHER, name)) { materialByOther = 1; } if (string.Equals(Global.Properties.ZERO_STRING, materialByOther.ToString())) { if (!string.Equals(Global.Properties.STATE_VALUE_EXISTING, state)) { sweight = WEIGHT_ZERO; } else { sweight = WEIGHT_THREE; } } int styleId = propertiesGetter.LineStyleId; if (styleId != 4) { ElementPropertiesSetter propertiesSetter = new ElementPropertiesSetter(); propertiesSetter.SetWeight(sweight); propertiesSetter.Apply(element); } element.ReplaceInModel(originalelement);
However i want to update the symbology of certain element of the cell header, not for all, so I am updating with below code, but OPM crashes at ReplaceInModel() function. What I am missing here?
//Function Caller private void UpdateSelective(){ IntPtr elementRef = element.GetNativeElementRef(); Element originalelement = Element.GetFromElementRef(elementRef); ApplyStyleSymbology(elementRef, 2); // Crashing Here element.ReplaceInModel(originalelement); } // Function Callee private void ApplyStyleSymbology(IntPtr elementRef, int style) { Element element = Element.GetFromElementRef(elementRef); IEnumerator<Element> childElements = element.GetChildren().GetEnumerator(); //if (!childElements.MoveNext()) return; while (childElements.MoveNext()) { Element currentElement = childElements.Current; if (currentElement.ElementType != MSElementType.CellHeader) { ElementPropertiesGetter propertiesGetter = new ElementPropertiesGetter(currentElement); int styleId = propertiesGetter.LineStyleId; LineStyleParameters parameters = propertiesGetter.LineStyle; MSElementType type = currentElement.ElementType; if (!(type == MSElementType.BsplineCurve || type == MSElementType.BsplineKnot || type == MSElementType.BsplinePole || type == MSElementType.Curve)) if (styleId != 4) { ElementPropertiesSetter propertiesSetter = new ElementPropertiesSetter(); propertiesSetter.SetLinestyle(style, parameters); propertiesSetter.Apply(currentElement); } } if (currentElement.ElementType == MSElementType.CellHeader) { IntPtr currentElementRef = currentElement.GetNativeElementRef(); ApplyStyleSymbology(currentElementRef, style); } } }
Varsha Reddy said:OPM crashes at ReplaceInModel() private void UpdateSelective() { IntPtr elementRef = element.GetNativeElementRef(); Element originalelement = Element.GetFromElementRef(elementRef); ApplyStyleSymbology(elementRef, 2); // Crashing Here element.ReplaceInModel(originalelement); }
private void UpdateSelective() { IntPtr elementRef = element.GetNativeElementRef(); Element originalelement = Element.GetFromElementRef(elementRef); ApplyStyleSymbology(elementRef, 2); // Crashing Here element.ReplaceInModel(originalelement); }
element
Oh... I missed the parameter
private void UpdateSelective(Element element)
{
...........
}
I tried that by getting element from element id but that did not worked, so have to do this. Let me check one more time by getting element from element id, and applying the same code for update.
Will soon update here.
Varsha Reddy said:the symbology of certain element of the cell header
It sounds like nonsense (but I guess it's only "lost in translation" issue: cell header is element itself, and other elements, representing the cell content, follow.
Varsha Reddy said:What I am missing here?
I am not sure, but I think you are missing to read my answers and linked discussion carefully (plus to do at least basic search for cell + replace keywords). It is well known long term bug in NET API.