dotnet/wpf · error · NotSupportedException
Cannot set read-only property
Error message
Cannot set read-only property '{0}'. What it means
DynamicMethodRuntime.SetValue is called to assign a member's value, but the member's invoker has no UnderlyingSetter (the property is read-only). It throws NotSupportedException with CantSetReadonlyProperty ('Cannot set a read-only property {0}'). The library throws this because there is no setter method to invoke.
Solutions
- Remove the attribute/element that assigns the read-only property from the XAML
- Add a setter to the property if it should be settable from XAML
- For get-only collection properties, ensure the collection itself supports Add so the item elements can be appended instead of assigning the property
Example fix
// before <Label ActualWidth="200" /> <!-- ActualWidth is read-only --> // after <Label Width="200" />
Defensive patterns
Strategy: try-catch
Validate before calling
static void EnsureSettable(Type t, string prop) { var p = t.GetProperty(prop); if (p != null && p.SetMethod == null) throw new InvalidOperationException($"{t}.{prop} is read-only and cannot be set from XAML"); } Type guard
static bool IsXamlSettable(System.Reflection.PropertyInfo p) => p?.SetMethod is { IsPublic: true }; Try / catch
try { Load(xaml); } catch (NotSupportedException ex) when (ex.Message.Contains("read-only property")) { throw new InvalidOperationException($"Remove assignment to read-only member: {ex.Message}", ex); } Prevention
- Never assign computed properties (ActualWidth, ActualHeight) in XAML
- Give collection properties get-only setters with addable collection types
- Keep view-model properties bindable-but-settable if XAML must write them
When it happens
Trigger: XAML load attempts to set a member whose CLR property has no setter (get-only, or get-only collection property whose collection cannot accept items via add), or markup assigns a value to a read-only property like FrameworkElement.ActualWidth.
Common situations: Setting built-in read-only WPF properties (ActualWidth, Templatized values) in XAML; view-model properties exposed read-only but referenced by bindings/styles in parsed XAML; collection properties declared without a setter and with non-addable collections.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot get write-only property
- Cannot get a XamlDeferringLoader from XamlValueConverter
- SR.CannotWriteToReadOnly
- SR.MustNotCallSetter
- SR.ParserDictionarySealed (the dictionary is sealed and…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/07157dae41d848fa.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Runtime/DynamicMethodRuntime.cs:261
throw new NotSupportedException(SR.Format(SR.CantGetWriteonlyProperty, member));
}
PropertyGetDelegate getterDelegate;
if (!PropertyGetDelegates.TryGetValue(getter, out getterDelegate))
{
getterDelegate = CreateGetDelegate(getter);
PropertyGetDelegates.Add(getter, getterDelegate);
}
return getterDelegate.Invoke(obj);
}
protected override void SetValue(XamlMember member, object obj, object value)
{
MethodInfo setter = member.Invoker.UnderlyingSetter;
if (setter is null)
{
throw new NotSupportedException(SR.Format(SR.CantSetReadonlyProperty, member));
}
PropertySetDelegate setterDelegate;
if (!PropertySetDelegates.TryGetValue(setter, out setterDelegate))
{
setterDelegate = CreateSetDelegate(setter);
PropertySetDelegates.Add(setter, setterDelegate);
}
setterDelegate.Invoke(obj, value);
}
private DelegateCreator CreateDelegateCreator(Type targetType)
{
const BindingFlags helperFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
// We are relying on WPF-generated delegate helper for now
// Expected signature: internal Delegate _CreateDelegate(Type delegateType, string handler)View on GitHub (pinned to 81131a70a4)