dotnet/maui · error · InvalidOperationException

Cannot convert "{strValue}" into {typeof(ButtonContentLayout

Error message

Cannot convert "{strValue}" into {typeof(ButtonContentLayout)}

What it means

Thrown by ButtonContentLayoutTypeConverter.ConvertFrom when the string splits into a number of parts (comma-separated, empties removed) that is neither 1 nor 2. The layout string must be a single position keyword or a spacing+position pair (in either order).

Source

Thrown at src/Controls/src/Core/Button/Button.cs:590

		public sealed class ButtonContentTypeConverter : TypeConverter
		{
			public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
				=> sourceType == typeof(string);

			public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
				=> false;

			public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
			{
				// IMPORTANT! Update ButtonContentDesignTypeConverter.IsValid if making changes here
				var strValue = value?.ToString();
				if (strValue == null)
					throw new InvalidOperationException($"Cannot convert null into {typeof(ButtonContentLayout)}");

				string[] parts = strValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

				if (parts.Length != 1 && parts.Length != 2)
					throw new InvalidOperationException($"Cannot convert \"{strValue}\" into {typeof(ButtonContentLayout)}");

				double spacing = DefaultSpacing;
				var position = ButtonContentLayout.ImagePosition.Left;

				var spacingFirst = char.IsDigit(parts[0][0]);

				int positionIndex = spacingFirst ? (parts.Length == 2 ? 1 : -1) : 0;
				int spacingIndex = spacingFirst ? 0 : (parts.Length == 2 ? 1 : -1);

				if (spacingIndex > -1)
					spacing = double.Parse(parts[spacingIndex], CultureInfo.InvariantCulture);

				if (positionIndex > -1)
					position = (ButtonContentLayout.ImagePosition)Enum.Parse(typeof(ButtonContentLayout.ImagePosition), parts[positionIndex], true);

				return new ButtonContentLayout(position, spacing);
			}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Use exactly one position keyword (Left/Right/Top/Bottom/Default) or a keyword plus one numeric spacing.
  2. Validate the split count equals 1 or 2 before assigning.
  3. Refer to the documented format: position first or spacing first, separated by a single comma.

Example fix

// before
<Button ContentLayout="Left,10,Right" />

// after
<Button ContentLayout="Left,10" />
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidLayoutString(string s)
{
    var parts = s.Split(',', StringSplitOptions.RemoveEmptyEntries);
    return parts.Length == 1 || parts.Length == 2;
}
if (!IsValidLayoutString(input)) throw new ArgumentException("Expected 1 or 2 parts");

Prevention

When it happens

Trigger: Strings like "Left,Top,Right" (3 parts), ",," (0 parts after empties removed), or "a,b,c". Passing a multi-token or empty string to the converter.

Common situations: Typing a wrong format in XAML (e.g. ContentLayout="Left,10,Extra"). Building the layout string programmatically with an unexpected number of segments. Localization inserting extra commas.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/e97e1e5e6481d334. Report an issue: GitHub.