dotnet/wpf · error · InvalidOperationException
SR.BitmapCacheBrush_TransformChanged
Error message
SR.BitmapCacheBrush_TransformChanged
What it means
BitmapCacheBrush does not support a Transform other than the default (null); the CoerceTransform coercion callback throws whenever a Transform is assigned. Transforms must be applied to the cached content or the rendering element, not the brush.
Solutions
- Remove the Transform assignment from BitmapCacheBrush
- Apply the transform to the Target visual or to the element using the brush (RenderTransform)
- If a transform on the cached rendering is required, restructure so the transform is baked into the cached visual
Example fix
// before
var brush = new BitmapCacheBrush { Target = visual, Transform = new TranslateTransform(10, 0) };
// after
var brush = new BitmapCacheBrush { Target = visual };
visual.RenderTransform = new TranslateTransform(10, 0); Defensive patterns
Strategy: validation
Validate before calling
if (brush is BitmapCacheBrush && brush.Transform != null) throw new InvalidOperationException("BitmapCacheBrush does not support Transform"); Type guard
bool supportsTransform(Brush b) => b is not BitmapCacheBrush;
Try / catch
try { cacheBrush.Transform = t; }
catch (InvalidOperationException) { targetVisual.RenderTransform = t; /* apply elsewhere */ } Prevention
- Never assign Transform to BitmapCacheBrush
- Apply transforms to the Target visual or the element's RenderTransform
- Audit brush setups copied from TileBrush/ImageBrush usage
When it happens
Trigger: Setting BitmapCacheBrush.Transform to any Transform instance (e.g. TranslateTransform, RotateTransform) in code, XAML (<BitmapCacheBrush><BitmapCacheBrush.Transform>...</...>), or via binding/animation.
Common situations: Developers porting brush code from TileBrush/ImageBrush (which support Transform) to BitmapCacheBrush and carrying over the Transform assignment.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.BitmapCacheBrush_OpacityChanged
- SR.BitmapCacheBrush_RelativeTransformChanged
- Animation_NoTextChildren
- Animation_NoTextChildren
- Can only call SelectAll when SelectionMode is Multiple or…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7321f4d0ec4bc3fa.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/BitmapCacheBrush.cs:362
{
Debug.Assert(_reentrancyFlag); // Exit must be matched with Enter. See Enter comments.
_reentrancyFlag = false;
}
private static object CoerceOpacity(DependencyObject d, object value)
{
if ((double)value != (double)OpacityProperty.GetDefaultValue(typeof(BitmapCacheBrush)))
{
throw new InvalidOperationException(SR.BitmapCacheBrush_OpacityChanged);
}
return 1.0;
}
private static object CoerceTransform(DependencyObject d, object value)
{
if ((Transform)value != (Transform)TransformProperty.GetDefaultValue(typeof(BitmapCacheBrush)))
{
throw new InvalidOperationException(SR.BitmapCacheBrush_TransformChanged);
}
return null;
}
private static object CoerceRelativeTransform(DependencyObject d, object value)
{
if ((Transform)value != (Transform)RelativeTransformProperty.GetDefaultValue(typeof(BitmapCacheBrush)))
{
throw new InvalidOperationException(SR.BitmapCacheBrush_RelativeTransformChanged);
}
return null;
}
private static void StaticInitialize(Type typeofThis)
{
OpacityProperty.OverrideMetadata(typeofThis, new IndependentlyAnimatedPropertyMetadata(1.0, propertyChangedCallback: null, CoerceOpacity));
TransformProperty.OverrideMetadata(typeofThis, new UIPropertyMetadata(null, propertyChangedCallback: null, CoerceTransform));
RelativeTransformProperty.OverrideMetadata(typeofThis, new UIPropertyMetadata(null, propertyChangedCallback: null, CoerceRelativeTransform));View on GitHub (pinned to 81131a70a4)