{"record":{"id":"cd8271d755f8a80f","repo":"dotnet/wpf","slug":"sr-textboxbase-cantsetisundoenabledinsidechangeblock","errorCode":null,"errorMessage":"SR.TextBoxBase_CantSetIsUndoEnabledInsideChangeBlock","messagePattern":"SR\\.TextBoxBase_CantSetIsUndoEnabledInsideChangeBlock","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/TextBoxBase.cs","lineNumber":1627,"sourceCode":"            }\n        }\n\n\n        /// <summary>\n        /// Helper method to update the IsUndoEnabled flag within UndoManager\n        /// attached to the TextBox.\n        /// </summary>\n        /// <param name=\"value\">\n        /// New Value of IsUndoEnabled flag.\n        /// </param>\n        internal void ChangeUndoEnabled(bool value)\n        {\n            // REVIEW:benwest:9/1/2005: does throwing exceptions here really work?\n            // Isn't the property value already changed?  We don't want the property value\n            // to change....\n            if (this.TextSelectionInternal.ChangeBlockLevel > 0)\n            {\n                throw new InvalidOperationException(SR.TextBoxBase_CantSetIsUndoEnabledInsideChangeBlock);\n            }\n\n            UndoManager undoManager = UndoManager.GetUndoManager(this);\n            if (undoManager != null)\n            {\n                if (!value && undoManager.IsEnabled)\n                {\n                    undoManager.Clear();\n                }\n                undoManager.IsEnabled = value;\n            }\n        }\n\n        /// <summary>\n        /// Helper method to update the UndoLimit in UndoManager\n        /// attached to the TextBox.\n        /// </summary>\n        /// <param name=\"value\">","sourceCodeStart":1609,"sourceCodeEnd":1645,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/TextBoxBase.cs#L1609-L1645","documentation":"Setting IsUndoEnabled on a TextBoxBase while a change block (BeginChange...EndChange) is open is rejected with an InvalidOperationException. Toggling the undo manager inside a change block would corrupt the undo stack, so WPF forbids it. The check runs in the IsUndoEnabled property-change callback.","triggerScenarios":"Assigning textBox.IsUndoEnabled = false (or true) inside a BeginChange()/EndChange() block, including from code invoked by a property-changed handler or TextChanged event raised during the block.","commonSituations":"Undo configuration code that reacts to TextChanged and tries to disable undo mid-edit; refactoring that moved a property setter inside an edit transaction.","solutions":["Move the IsUndoEnabled assignment outside the BeginChange/EndChange block.","Defer the assignment until after EndChange completes (e.g. Dispatcher.BeginInvoke or a flag checked after EndChange).","If you must reconfigure undo, end the current change block first, then set the property, then begin a new block."],"exampleFix":"// before\ntextBox.BeginChange();\ntextBox.IsUndoEnabled = false; // throws inside change block\ntextBox.EndChange();\n// after\ntextBox.BeginChange();\ntextBox.EndChange();\ntextBox.IsUndoEnabled = false;","handlingStrategy":"validation","validationCode":"bool isInsideChangeBlock = textBox.IsSelectionActive && GetChangeBlockLevel(textBox) > 0; // helper using reflection over TextEditor.Selection.ChangeBlockLevel\nif (!isInsideChangeBlock) textBox.IsUndoEnabled = false;","typeGuard":null,"tryCatchPattern":"try\n{\n    textBox.IsUndoEnabled = false;\n}\ncatch (InvalidOperationException)\n{\n    Dispatcher.BeginInvoke(new Action(() => textBox.IsUndoEnabled = false), DispatcherPriority.Background);\n}","preventionTips":["Configure IsUndoEnabled only at control initialization","Never mutate undo settings inside TextChanged or BeginChange blocks","Defer property writes with Dispatcher when reacting to edit events"],"tags":["wpf","textbox","undo","invalid-operation"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}