Created
May 24, 2021 22:45
-
-
Save pictos/f410a6983e75b2f3a993ce092c970a36 to your computer and use it in GitHub Desktop.
Spec to using an Attached property
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class CornerRadiusEffect | |
{ | |
public static readonly BindableProperty CornerRadiusProperty = BindableProperty.CreateAttached( | |
nameof(CornerRadius), | |
typeof(CornerRadius), | |
typeof(CornerRadiusEffect), | |
default(CornerRadius), | |
propertyChanged: OnCornerRadiusPropertyChanged); | |
static void OnCornerRadiusPropertyChanged(BindableObject bindable, object oldValue, object newValue) | |
{ | |
if (!(bindable is VisualElement elementView)) | |
return; | |
elementView.SizeChanged -= ElementView_SizeChanged; | |
elementView.SizeChanged += ElementView_SizeChanged; | |
UpdateClip(elementView); | |
} | |
static void ElementView_SizeChanged(object sender, EventArgs e) | |
{ | |
UpdateClip((VisualElement)sender); | |
} | |
public static CornerRadius GetCornerRadius(BindableObject bindable) | |
=> (CornerRadius)(bindable?.GetValue(CornerRadiusProperty) ?? throw new ArgumentNullException(nameof(bindable))); | |
public static void SetCornerRadius(BindableObject bindable, CornerRadius value) | |
=> bindable?.SetValue(CornerRadiusProperty, value); | |
static void UpdateClip(VisualElement elementView) | |
{ | |
var rect = new Rect(0, 0, elementView.Width, elementView.Height); | |
var cornerRadius = GetCornerRadius(rect, elementView); | |
if (cornerRadius == default) | |
{ | |
elementView.Clip = null; | |
return; | |
} | |
if (!(elementView.Clip is RoundRectangleGeometry roundRectangleGeometry)) | |
{ | |
elementView.Clip = new RoundRectangleGeometry(cornerRadius, rect); | |
return; | |
} | |
roundRectangleGeometry.CornerRadius = cornerRadius; | |
roundRectangleGeometry.Rect = rect; | |
} | |
static CornerRadius GetCornerRadius(Rect rect, VisualElement elementView) | |
{ | |
var maxCornerRadius = Math.Min(rect.Width, rect.Height) / 2; | |
if (maxCornerRadius <= 0) | |
return default; | |
var cornerRadius = GetCornerRadius(elementView); | |
if (cornerRadius.TopLeft > maxCornerRadius || | |
cornerRadius.TopRight > maxCornerRadius || | |
cornerRadius.BottomLeft > maxCornerRadius || | |
cornerRadius.BottomRight > maxCornerRadius) | |
{ | |
return new CornerRadius( | |
Math.Min(cornerRadius.TopLeft, maxCornerRadius), | |
Math.Min(cornerRadius.TopRight, maxCornerRadius), | |
Math.Min(cornerRadius.BottomLeft, maxCornerRadius), | |
Math.Min(cornerRadius.BottomRight, maxCornerRadius)); | |
} | |
return cornerRadius; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment