1: using System;
2: using System.Windows;
3: using System.Windows.Shapes;
4:
5: /// <summary>
6: /// Contains attached properties for specifiying rounded ends on a Rectangle
7: /// </summary>
8: public static class RoundCaps
9: {
10: /// <summary>
11: /// Attached Dependency Property for the IsRounded property
12: /// </summary>
13: public static readonly DependencyProperty IsRoundedProperty = DependencyProperty.RegisterAttached(
14: "IsRounded",
15: typeof(bool),
16: typeof(RoundCaps),
17: new PropertyMetadata(false, IsRoundedChanged));
18:
19: /// <summary>
20: /// Attached Dependency Property for the RoundCapsRatio property
21: /// </summary>
22: public static readonly DependencyProperty RoundCapsRatioProperty = DependencyProperty.RegisterAttached(
23: "RoundCapsRatio",
24: typeof(double),
25: typeof(RoundCaps),
26: new PropertyMetadata(0.5, RoundCapsRatioChanged));
27:
28: /// <summary>
29: /// Gets a value indicating if the Rectangle is rounded.
30: /// </summary>
31: /// <param name="d">The rectangle.</param>
32: /// <returns>true if the rectangle is rounded, else false</returns>
33: public static bool GetIsRounded(DependencyObject rectangle)
34: {
35: return (bool)rectangle.GetValue(IsRoundedProperty);
36: }
37:
38: /// <summary>
39: /// Sets a value indicating if the Rectangle is rounded.
40: /// </summary>
41: /// <param name="rectangle">The rectangle.</param>
42: /// <param name="value">true if the rectangle is rounded, else false.</param>
43: public static void SetIsRounded(DependencyObject rectangle, object value)
44: {
45: rectangle.SetValue(IsRoundedProperty, value);
46: }
47:
48: /// <summary>
49: /// Gets the roundedness ratio of the rectangle.
50: /// </summary>
51: /// <param name="rectangle">The ratio, relative to the lesser value of the rectangle's height and width.</param>
52: /// <returns>The ratio currently applied when calculating the roundedness</returns>
53: public static double GetRoundCapsRatio(DependencyObject rectangle)
54: {
55: return (double)rectangle.GetValue(RoundCapsRatioProperty);
56: }
57:
58: /// <summary>
59: /// Sets the roundedness ratio of the rectangle.
60: /// </summary>
61: /// <param name="rectangle">The ratio, relative to the lesser value of the rectangle's height and width.</param>
62: /// <returns>The ratio to be applied when calculating the roundedness</returns>
63: public static void SetRoundCapsRatio(DependencyObject d, object value)
64: {
65: d.SetValue(RoundCapsRatioProperty, value);
66: }
67:
68: private static void IsRoundedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
69: {
70: Rectangle rect = d as Rectangle;
71: if (null == d)
72: return;
73:
74: bool isRounded = (bool)e.NewValue == true;
75: if (isRounded)
76: {
77: rect.SizeChanged += RectSizeChanged;
78: UpdateRectangle(rect);
79: }
80: else
81: {
82: rect.SizeChanged -= RectSizeChanged;
83: }
84: }
85:
86: private static void RoundCapsRatioChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
87: {
88: Rectangle rect = d as Rectangle;
89: if (null == rect)
90: {
91: return;
92: }
93:
94: UpdateRectangle(rect);
95: }
96:
97: private static void RectSizeChanged(object sender, SizeChangedEventArgs e)
98: {
99: Rectangle rect = sender as Rectangle;
100: if (null == rect)
101: {
102: return;
103: }
104:
105: UpdateRectangle(rect);
106: }
107:
108: private static void UpdateRectangle(Rectangle rect)
109: {
110: double ratio = (double)rect.GetValue(RoundCapsRatioProperty);
111:
112: rect.RadiusX = Math.Min(rect.ActualHeight, rect.ActualWidth) * ratio;
113: rect.RadiusY = rect.RadiusX;
114: }
115: }