dotnet/wpf · error · ArgumentException
SR.Format(SR.PropertyNotBindable, dp.Name)
Error message
SR.Format(SR.PropertyNotBindable, dp.Name)
What it means
CreateBindingExpression validates that the target DependencyProperty allows data binding: it must be writable and its FrameworkPropertyMetadata must have IsDataBindingAllowed (not read-only and not restrictions like not-data-bindable). Binding a read-only or non-bindable property is rejected with an ArgumentException naming the property.
Solutions
- Bind only to writable, data-bindable dependency properties — check dp.ReadOnly and FrameworkPropertyMetadata.IsDataBindingAllowed first
- For read-only values, bind the opposite direction (bind another property to the read-only one via OneWay from it), or use the read-only DP's ChangeMachine/Listen via descriptor
- Expose your own bindable DP and synchronize it from the read-only source if binding input is required
Example fix
// before
label.SetBinding(UIElement.ActualWidthProperty, new Binding("Width")); // ArgumentException: PropertyNotBindable
// after
label.SetBinding(Label.WidthProperty, new Binding("Width")); Defensive patterns
Strategy: validation
Validate before calling
var md = dp.GetMetadata(target.GetType()) as FrameworkPropertyMetadata;
if (dp.ReadOnly || md == null || !md.IsDataBindingAllowed) throw new ArgumentException($"{dp.Name} is not data-bindable"); Type guard
static bool IsBindable(DependencyProperty dp, DependencyObject d) => !dp.ReadOnly && dp.GetMetadata(d.DependencyObjectType) is FrameworkPropertyMetadata fmd && fmd.IsDataBindingAllowed;
Try / catch
try { target.SetBinding(dp, binding); } catch (ArgumentException ex) when (ex.Message.Contains("bindable") || ex.ParamName == "dp") { /* bind a writable DP instead */ } Prevention
- Check dp.ReadOnly and IsDataBindingAllowed before SetBinding
- Avoid binding read-only DPs like ActualWidth; bind from them instead
- Use compile-time-known writable DPs in helper libraries
When it happens
Trigger: Calling BindingOperations.SetBinding (or creating a BindingExpression) targeting a read-only dependency property (e.g. UIElement.HasStroke... style read-only DPs), or a property whose metadata sets IsDataBindingAllowed=false (e.g. reads-only triggers properties).
Common situations: Attempting to bind to read-only DPs like ActualWidth, ItemsControl.Items, or trigger-only properties; framework migrations exposing properties as read-only; generic helper code that binds any DP without checking dp.ReadOnly.
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.CannotDetermineSortByPropertiesForCollection
- SR.Format(SR.PropertyToSortByNotFoundOnType, typeName…
- SR.RelativeSourceModeInvalid
- " }} " element found. Expected fixed page element ( }} ).
- ' ' ContentType is not valid.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/49916924a22c91d4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingExpression.cs:394
get { return GetReference(_dataItem) == DisconnectedItem; }
}
//------------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
// Create a new BindingExpression from the given Bind description
internal static BindingExpression CreateBindingExpression(DependencyObject d,
DependencyProperty dp,
Binding binding,
BindingExpressionBase parent)
{
FrameworkPropertyMetadata fwMetaData = dp.GetMetadata(d.DependencyObjectType) as FrameworkPropertyMetadata;
if ((fwMetaData != null && !fwMetaData.IsDataBindingAllowed) || dp.ReadOnly)
throw new ArgumentException(SR.Format(SR.PropertyNotBindable, dp.Name), nameof(dp));
// create the BindingExpression
BindingExpression bindExpr = new BindingExpression(binding, parent);
bindExpr.ResolvePropertyDefaultSettings(binding.Mode, binding.UpdateSourceTrigger, fwMetaData);
// Two-way Binding with an empty path makes no sense
if (bindExpr.IsReflective && binding.XPath == null &&
(binding.Path == null || String.IsNullOrEmpty(binding.Path.Path)))
throw new InvalidOperationException(SR.TwoWayBindingNeedsPath);
return bindExpr;
}
// Note: For Nullable types, DefaultValueConverter is created for the inner type of the Nullable.
// Nullable "Drill-down" service is not provided for user provided Converters.
internal void SetupDefaultValueConverter(Type type)View on GitHub (pinned to 81131a70a4)