{"record":{"id":"b533577ae9ed4b86","repo":"dotnet/wpf","slug":"cannotchangeaftersealed-sr-format-sr-seekstoryboard","errorCode":"CannotChangeAfterSealed","errorMessage":"SR.Format(SR.CannotChangeAfterSealed, \"SeekStoryboard\")","messagePattern":"SR\\.Format\\(SR\\.CannotChangeAfterSealed, \"SeekStoryboard\"\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Media/Animation/SeekStoryboard.cs","lineNumber":37,"sourceCode":"    /// </summary>\n    public sealed class SeekStoryboard : ControllableStoryboardAction\n{\n    /// <summary>\n    ///     A time offset to use for this action.  If it is never explicitly\n    /// specified, it will be zero.\n    /// </summary>\n    // [DefaultValue(TimeSpan.Zero)] - not usable because TimeSpan.Zero is not a constant expression.\n    public TimeSpan Offset\n    {\n        get\n        {\n            return _offset;\n        }\n        set\n        {\n            if (IsSealed)\n            {\n                throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, \"SeekStoryboard\"));\n            }\n            // TimeSpan is a struct and can't be null - hence no ArgumentNullException check.\n            _offset = value;\n        }\n    }\n\n    /// <summary>\n    /// This method is used by TypeDescriptor to determine if this property should\n    /// be serialized.\n    /// </summary>\n    // Because we can't use [DefaultValue(TimeSpan.Zero)] - TimeSpan.Zero is not a constant expression.\n    [EditorBrowsable(EditorBrowsableState.Never)]\n    public bool ShouldSerializeOffset()\n    {\n        return !(TimeSpan.Zero.Equals(_offset));\n    }\n    \n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Media/Animation/SeekStoryboard.cs#L19-L55","documentation":"SeekStoryboard.Offset's setter throws InvalidOperationException once the SeekStoryboard object is sealed (read-only). ControllableStoryboardAction objects become sealed when they are in use inside a Storyboard/trigger tree, freezing their configuration.","triggerScenarios":"Setting the Offset property on a SeekStoryboard instance that has already been sealed — typically after it has been applied to a running storyboard or shared/attached in a template.","commonSituations":"Reusing a single SeekStoryboard instance across multiple seek operations from code; mutating a template-defined SeekStoryboard at runtime.","solutions":["Create a new SeekStoryboard instance for each seek and set Offset before use.","Set Offset immediately after construction, before adding the action to any trigger or storyboard.","If sharing is needed, keep a prototype and clone it per use."],"exampleFix":"// before\nsharedSeek.Offset = TimeSpan.FromSeconds(3); // throws after first use\n\n// after\nvar seek = new SeekStoryboard { Storyboard = targetStoryboard, Offset = TimeSpan.FromSeconds(3), Origin = TimeSeekOrigin.BeginTime };","handlingStrategy":"type-guard","validationCode":"if (seek.IsSealed) seek = new SeekStoryboard { Storyboard = seek.Storyboard, Offset = newOffset, Origin = seek.Origin };","typeGuard":"static SeekStoryboard EnsureMutable(SeekStoryboard s, TimeSpan newOffset) => s.IsSealed ? new SeekStoryboard { Storyboard = s.Storyboard, Offset = newOffset, Origin = s.Origin } : s;","tryCatchPattern":"try { seek.Offset = newOffset; } catch (InvalidOperationException) { seek = new SeekStoryboard { /* reconfigure */ }; }","preventionTips":["Treat storyboard action objects as immutable once used","Create a fresh SeekStoryboard per seek operation","Set all properties immediately after construction"],"tags":["wpf","storyboard","animation","sealed-object","immutable-state"],"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-22T01:17:13.364Z"}