Revit批量转换全大写TextNote为句首大写失败求助
问题分析与修复方案
你的代码转换逻辑本身是可行的,但无法将修改写入Revit模型,通常由以下几个关键问题导致,对应修复方法如下:
1. 视图未手动刷新,修改未实时显示
Revit事务提交后不会自动强制刷新视图,即使元素已被修改,你可能在界面上看不到变化,误以为写入失败。在事务提交后添加视图刷新代码:
trans.Commit(); // 刷新当前激活视图,确保修改可见 uiDoc.RefreshActiveView(); // 强制文档重新生成,同步数据状态 doc.Regenerate(); TaskDialog.Show("Change to Sentence Case", count + " text notes have been changed");
2. 未检查元素可编辑状态
部分TextNote可能被锁定、属于不可编辑工作集,或是位于链接文档中,导致无法修改。在处理前添加可编辑性检查:
foreach (var text in textNotes) { try { // 跳过不可编辑的元素,避免修改失败 if (!doc.IsModifiable(text)) { continue; } var currentFormattedText = text.GetFormattedText(); var currentPlainText = currentFormattedText.GetPlainText(); // 优化冗余的GetFormattedText()调用 var output = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(currentPlainText.ToLower()); currentFormattedText.SetPlainText(output); text.SetFormattedText(currentFormattedText); count++; } catch (Exception ex) { message = ex.Message; trans.RollBack(); // 出错时回滚事务,避免部分修改残留 return Result.Failed; } }
3. 异常处理未回滚事务
当前循环内的catch直接返回Result.Failed,但未回滚事务,可能导致部分元素被修改后事务处于异常状态,出现数据不一致。需在catch块中添加事务回滚逻辑:
catch (Exception ex) { message = ex.Message; trans.RollBack(); return Result.Failed; }
4. 链接文档中的TextNote未被处理
如果目标TextNote位于链接的Revit文档中,当前代码只会收集主文档元素,需新增链接文档的处理逻辑:
// 遍历并处理链接文档中的TextNote var linkInstances = new FilteredElementCollector(doc) .OfClass(typeof(RevitLinkInstance)) .Cast<RevitLinkInstance>(); foreach (var linkInstance in linkInstances) { var linkedDoc = linkInstance.GetLinkDocument(); if (linkedDoc == null || !linkedDoc.IsModifiable) continue; var linkedTextNotes = new FilteredElementCollector(linkedDoc) .OfCategory(BuiltInCategory.OST_TextNotes) .WhereElementIsNotElementType() .ToElements().Cast<TextNote>(); foreach (var text in linkedTextNotes) { if (!linkedDoc.IsModifiable(text)) continue; // 执行相同的格式转换逻辑 var currentFormattedText = text.GetFormattedText(); var currentPlainText = currentFormattedText.GetPlainText(); var output = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(currentPlainText.ToLower()); currentFormattedText.SetPlainText(output); text.SetFormattedText(currentFormattedText); count++; } }
修复后的完整代码示例
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { var uiDoc = commandData.Application.ActiveUIDocument; var doc = uiDoc.Document; try { using Transaction trans = new(doc, "Change to sentence case"); trans.Start(); var count = 0; // 处理主文档的TextNote var textNotes = new FilteredElementCollector(doc) .OfCategory(BuiltInCategory.OST_TextNotes) .WhereElementIsNotElementType() .ToElements().Cast<TextNote>(); foreach (var text in textNotes) { try { if (!doc.IsModifiable(text)) continue; var currentFormattedText = text.GetFormattedText(); var currentPlainText = currentFormattedText.GetPlainText(); var output = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(currentPlainText.ToLower()); currentFormattedText.SetPlainText(output); text.SetFormattedText(currentFormattedText); count++; } catch (Exception ex) { message = ex.Message; trans.RollBack(); return Result.Failed; } } // 处理链接文档的TextNote(可选) var linkInstances = new FilteredElementCollector(doc) .OfClass(typeof(RevitLinkInstance)) .Cast<RevitLinkInstance>(); foreach (var linkInstance in linkInstances) { var linkedDoc = linkInstance.GetLinkDocument(); if (linkedDoc == null || !linkedDoc.IsModifiable) continue; var linkedTextNotes = new FilteredElementCollector(linkedDoc) .OfCategory(BuiltInCategory.OST_TextNotes) .WhereElementIsNotElementType() .ToElements().Cast<TextNote>(); foreach (var text in linkedTextNotes) { if (!linkedDoc.IsModifiable(text)) continue; var currentFormattedText = text.GetFormattedText(); var currentPlainText = currentFormattedText.GetPlainText(); var output = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(currentPlainText.ToLower()); currentFormattedText.SetPlainText(output); text.SetFormattedText(currentFormattedText); count++; } } trans.Commit(); // 刷新视图确保修改可见 uiDoc.RefreshActiveView(); doc.Regenerate(); TaskDialog.Show("Change to Sentence Case", count + " text notes have been changed"); return Result.Succeeded; } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { return Result.Cancelled; } catch (Exception ex) { message = ex.Message; return Result.Failed; } }
内容的提问来源于stack exchange,提问作者Gosmith
相关产品推荐
相关产品推荐

