dotnet/wpf · error · InvalidOperationException

SR.BitmapCacheBrush_OpacityChanged

Error message

SR.BitmapCacheBrush_OpacityChanged

What it means

BitmapCacheBrush deliberately does not support a non-default Opacity; the CoerceOpacity coercion callback throws whenever Opacity is set to anything other than the default (1.0). The brush's opacity must be controlled through the cached content or the Target brush instead.

Solutions

  1. Do not set Opacity on BitmapCacheBrush; leave it at the default 1.0
  2. Apply the desired opacity to the Target brush or to the element rendering the brush (UIElement.Opacity)
  3. If opacity effects are needed, wrap the cached content with an element/brush that supports opacity

Example fix

// before
var brush = new BitmapCacheBrush { Target = visual, Opacity = 0.5 };
// after
var brush = new BitmapCacheBrush { Target = visual };
element.Opacity = 0.5; // or set opacity on the target visual
Defensive patterns

Strategy: validation

Validate before calling

if (brush is BitmapCacheBrush && brush.Opacity != 1.0) throw new InvalidOperationException("BitmapCacheBrush does not support custom Opacity");

Type guard

bool supportsOpacity(Brush b) => b is not BitmapCacheBrush;

Try / catch

try { cacheBrush.Opacity = value; }
catch (InvalidOperationException) { element.Opacity = value; /* apply elsewhere */ }

Prevention

When it happens

Trigger: Setting BitmapCacheBrush.Opacity to any value other than 1.0 (the default), in code (brush.Opacity = 0.5), XAML (<BitmapCacheBrush Opacity="0.5"/>), or via animation/binding targeting Opacity.

Common situations: Developers assuming Brush.Opacity works uniformly across brush types and applying opacity to BitmapCacheBrush copied from another brush's usage.

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


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/f867b1a94e60e5d6. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/BitmapCacheBrush.cs:353

                _reentrancyFlag = true;
                return true;
            }
        }

        /// <summary>
        /// Exits the BitmapCacheBrush. For more details see Enter method.
        /// </summary>
        internal void Exit()
        {
            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);

View on GitHub (pinned to 81131a70a4)