dotnet/maui · error · InvalidOperationException
Cannot change a binding while it's applied
Error message
Cannot change a binding while it's applied
What it means
Thrown by ThrowIfApplied() (called from many property setters) when IsApplied is true, meaning the BindingBase has already been attached to a target BindableObject. MAUI bindings are not designed to be mutated after application; setters call ThrowIfApplied to enforce this invariant.
Source
Thrown at src/Controls/src/Core/BindingBase.cs:160
/// </remarks>
public static void EnableCollectionSynchronization(IEnumerable collection, object context, CollectionSynchronizationCallback callback)
{
if (collection == null)
throw new ArgumentNullException(nameof(collection));
if (callback == null)
throw new ArgumentNullException(nameof(callback));
SynchronizedCollections.Add(collection, new CollectionSynchronizationContext(context, callback));
}
/// <summary>Throws <see cref="InvalidOperationException" /> if the binding has already been applied.</summary>
/// <remarks>Used by property setters to prevent mutation after the binding has been attached to a target.</remarks>
/// <exception cref="InvalidOperationException">The binding has already been applied.</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void ThrowIfApplied()
{
if (IsApplied)
throw new InvalidOperationException("Cannot change a binding while it's applied");
}
internal virtual void Apply(bool fromTarget)
=> IsApplied = true;
internal virtual void Apply(object context, BindableObject bindObj, BindableProperty targetProperty, bool fromBindingContextChanged, SetterSpecificity specificity)
=> IsApplied = true;
internal abstract BindingBase Clone();
internal virtual object GetSourceValue(object value, Type targetPropertyType)
{
if (value == null && TargetNullValue != null)
return TargetNullValue;
if (StringFormat != null && TryFormat(StringFormat, value, out var formatted))
return formatted;
View on GitHub (pinned to f377ff1c5e)
Solutions
- Create a fresh Binding instance whenever configuration must change; never mutate an applied binding.
- Set all desired properties before calling SetBinding on the target.
- Call RemoveBinding / re-create the binding rather than editing properties in place.
Example fix
// before — mutating after apply
element.SetBinding(Label.TextProperty, binding);
binding.StringFormat = "{0:C}"; // throws
// after
var binding = new Binding("Price") { StringFormat = "{0:C}" };
element.SetBinding(Label.TextProperty, binding); Defensive patterns
Strategy: validation
Validate before calling
// Configure fully BEFORE applying; never mutate after SetBinding
var binding = new Binding("Name")
{
Mode = BindingMode.OneWay,
StringFormat = "{0}"
};
element.SetBinding(Label.TextProperty, binding); Prevention
- Treat Binding as immutable after SetBinding.
- Build a new Binding instance when configuration must change.
- Cache binding configuration data, not live binding instances.
When it happens
Trigger: Setting Mode, Path, Converter, Source, StringFormat, or any other property on a Binding after it has been applied to a BindableObject via SetBinding. Reusing the same Binding instance and mutating it after it is live. Applying a binding then trying to reconfigure it in a handler.
Common situations: Caching a Binding instance and reconfiguring it on view reuse. Setting binding properties inside an event handler that fires after the binding is already attached. Misunderstanding that SetBinding finalizes the binding.
Related errors
- binding
- self
- targetProperty
- Call to Create<{typeof(TSource)}, {typeof(TProperty)}> could
- Call to Create<{typeof(TSource)}, {typeof(TProperty)}>() was
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/2fe1977cbaf86d96.
Report an issue: GitHub.