{"record":{"id":"18e3553a6a77b784","repo":"dotnet/wpf","slug":"sr-generaltransform-transformfailed","errorCode":null,"errorMessage":"SR.GeneralTransform_TransformFailed","messagePattern":"SR\\.GeneralTransform_TransformFailed","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GeneralTransform.cs","lineNumber":46,"sourceCode":"\n        /// <summary>\n        /// Transform a point\n        /// \n        /// If the transformation does not succeed, this will throw an InvalidOperationException.\n        /// If you don't want to try/catch, call TryTransform instead and check the boolean it\n        /// returns.\n        ///\n        /// Note that this method will always succeed when called on a subclass of Transform\n        /// </summary>\n        /// <param name=\"point\">Input point</param>\n        /// <returns>The transformed point</returns>\n        public Point Transform(Point point)\n        {\n            Point transformedPoint;\n\n            if (!TryTransform(point, out transformedPoint))\n            {\n                throw new InvalidOperationException(SR.Format(SR.GeneralTransform_TransformFailed, null));\n            }\n\n            return transformedPoint;\n        }\n        \n        /// <summary>\n        /// Transforms the bounding box to the smallest axis aligned bounding box\n        /// that contains all the points in the original bounding box\n        /// </summary>\n        /// <param name=\"rect\">Bounding box</param>\n        /// <returns>The transformed bounding box</returns>\n        public abstract Rect TransformBounds(Rect rect);\n\n\n        /// <summary>\n        /// Returns the inverse transform if it has an inverse, null otherwise\n        /// </summary>        \n        public abstract GeneralTransform Inverse { get; }","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GeneralTransform.cs#L28-L64","documentation":"GeneralTransform.Transform(Point) throws InvalidOperationException wrapping SR.GeneralTransform_TransformFailed when TryTransform returns false, i.e., the transform could not map the point (typically because the visual is not connected to a presentation source or the transform is degenerate/non-invertible). Unlike TryTransform, Transform treats failure as an exception rather than returning false.","triggerScenarios":"Calling Transform, TransformToAncestor, or TransformToDescendant on a Visual whose transform matrix is singular (zero scale) or whose coordinates cannot be computed because the visual has no valid layout/presentation source yet.","commonSituations":"Hit-testing or positioning popups/context menus before the element is loaded and rendered (IsLoaded == false); transforms involving a ScaleTransform with scale 0; adorner coordinate math (pointOnSelectionAdorner, pointOnInnerCanvas) running too early in the visual tree lifecycle.","solutions":["Prefer TryTransform and handle the false return instead of letting Transform throw.","Defer the transform until the visual is loaded (handle the Loaded event or check IsLoaded) so coordinates are valid.","Verify the transform matrix is invertible (no zero scale) before transforming.","Use PointToScreen/PointFromScreen alternatives if the visual is disconnected from the presentation source."],"exampleFix":"// before\nvar pt = generalTransform.Transform(anchorPoint);\n\n// after\nif (generalTransform.TryTransform(anchorPoint, out var pt))\n{\n    // use pt\n}\nelse\n{\n    pt = anchorPoint; // fallback\n}","handlingStrategy":"try-catch","validationCode":"bool canTransform = visual.IsLoaded && generalTransform != null && !generalTransform.Value.HasInverse == false; // prefer TryTransform\nif (!generalTransform.TryTransform(point, out _)) { /* skip or defer */ }","typeGuard":"bool IsTransformable(Visual v) => v != null && v.IsLoaded;","tryCatchPattern":"try\n{\n    transformed = generalTransform.Transform(point);\n}\ncatch (InvalidOperationException)\n{\n    // visual not ready or singular transform\n    transformed = point; // or defer until Loaded\n}","preventionTips":["Run coordinate transformations only after the element is loaded and measured (Loaded event).","Prefer TryTransform over Transform when failure is an expected, recoverable condition.","Check transform matrices for zero-scale/degenerate values before mapping points.","For popup/context-menu placement, recompute offsets in the PlacementTarget's Loaded handler rather than in the constructor."],"tags":["wpf","transform","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"}