Repository: unoplatform/uno
File: src/Uno.UI/UI/Xaml/Shapes/Shape.cs (C#)

Code before:
		{
			if ((oldValue is null) ^ (newValue is null))
			{
				// Moving from null to non-null or vice-versa affects measure.
				InvalidateMeasure();
			}

			Brush.SetupBrushChanged(oldValue, newValue, ref _strokeBrushChanged, () => OnStrokeBrushChanged());
		}

		#endregion

		#region StrokeThickness Dependency Property
		public double StrokeThickness
		{
			get => (double)this.GetValue(StrokeThicknessProperty);
			set => this.SetValue(StrokeThicknessProperty, value);
		}

		public static DependencyProperty StrokeThicknessProperty { get; } = DependencyProperty.Register(
			nameof(StrokeThickness),
			typeof(double),
			typeof(Shape),
			new FrameworkPropertyMetadata(
				defaultValue: 1.0d,
				FrameworkPropertyMetadataOptions.AffectsMeasure,
				propertyChangedCallback: (s, e) => ((Shape)s).OnStrokeThicknessChanged()
			)
		);

		private void OnStrokeThicknessChanged()
		{
			if (Stroke is not null)
			{
				// Changing stroke thickness will only have effect if Stroke is not null.
				InvalidateMeasure();
			}
		}
		#endregion

		#region Stretch Dependency Property
		public Stretch Stretch
		{
			get => (Stretch)this.GetValue(StretchProperty);
			set => this.SetValue(StretchProperty, value);
		}

		public static DependencyProperty StretchProperty { get; } = DependencyProperty.Register(
			"Stretch",
			typeof(Stretch),
			typeof(Shape),

Review comment (suggestion):
This was intentionally not added. In `OnStrokeThicknessChanged`, we only invalidate measure if stroke is not null.

Code after:
			new FrameworkPropertyMetadata(
				defaultValue: null,
				propertyChangedCallback: (s, e) => ((Shape)s).OnStrokeChanged((Brush)e.OldValue, (Brush)e.NewValue)
			) // Perf: WinUI uses AffectsMeasure, we optimize this and only invalidate measure if needed
		);

		private void OnStrokeChanged(Brush oldValue, Brush newValue)
		{
			if ((oldValue is null) ^ (newValue is null))
			{
				// Moving from null to non-null or vice-versa affects measure.
				InvalidateMeasure();
			}

#if __SKIA__
			// On Skia, OnStrokeBrushChanged will call GetOrCreateCompositionBrush and assign this to _shape.StrokeBrush
			// In this case, we don't really want to listen to brush changes as the Brush is responsible for synchronizing its internal composition brush
			OnStrokeBrushChanged();
#else
			Brush.SetupBrushChanged(oldValue, newValue, ref _strokeBrushChanged, () => OnStrokeBrushChanged());
#endif
		}

		#endregion

		#region StrokeThickness Dependency Property
		public double StrokeThickness
		{
			get => (double)this.GetValue(StrokeThicknessProperty);
			set => this.SetValue(StrokeThicknessProperty, value);
		}

		public static DependencyProperty StrokeThicknessProperty { get; } = DependencyProperty.Register(
			nameof(StrokeThickness),
			typeof(double),
			typeof(Shape),
			new FrameworkPropertyMetadata(
				defaultValue: 1.0d,
				propertyChangedCallback: (s, e) => ((Shape)s).OnStrokeThicknessChanged()
			) // Perf: WinUI uses AffectsMeasure, we optimize this and only invalidate measure if Stroke is not null
		);

		private void OnStrokeThicknessChanged()
		{
			if (Stroke is not null)
			{
				// Changing stroke thickness will only have effect if Stroke is not null.
				InvalidateMeasure();
			}
		}
		#endregion